Java Apuntes Imprimir
Java Apuntes Imprimir
Hay varios tipos de clases que se utilizan en aplicaciones en tiempo real como clases anidadas, clases
anónimas, expresiones lambda. (posteriormente aprenderá cada una de ellas en este blog.)
Aprende más
Clases en Java
IR AL ARTÍCULO
2. Qué es un Objeto
Un objeto es una unidad básica de Programación Orientada a Objetos y representa las entidades de la vida real. Declaración de objetos
Un programa típico de Java crea muchos objetos, que como usted sabe, interactúan al invocar métodos. Un
objeto consiste en:
A medida que declaramos variables como (tipo nombre;). Esto notifica al compilador que utilizaremos
el nombre para referirnos a los datos cuyo tipo es tipo. Con una variable primitiva, esta declaración también
reserva la cantidad adecuada de memoria para la variable. Entonces, para la variable de referencia, el tipo debe
ser estrictamente un nombre de clase concreto. En general, no podemos crear objetos de una clase abstracta o
una interfaz.
Perro clifford;
Si declaramos una variable de referencia (clifford) como la de arriba, su valor será indeterminado (nulo) hasta
que realmente se cree y se le asigne un objeto. Simplemente declarar una variable de referencia no crea un
objeto.
ⓘ
4. Inicializando un objeto
Estado: está representado por atributos de un objeto. También refleja las propiedades de un objeto.
Comportamiento: se representa mediante métodos de un objeto. También refleja la respuesta de un El nuevo operador instancia una clase asignando memoria para un nuevo objeto y devolviendo una referencia a
objeto con otros objetos. esa memoria. El nuevo operador también invoca el constructor de clase.
Identidad: le da un nombre único a un objeto y permite que un objeto interactúe con otros objetos.
Ejemplo de un objeto: Perro Ejemplo:
// Declaración de clase
System.out.println(clifford.toString());
}
{
// Variables de instancia
Salida:
String nombre;
String raza;
int edad;
Hola mi nombre es clifford.
this.edad = edad;
Perro clifford = new Perro("clifford","pitbull", 5, "blanco");
this.color = color;
Nota: Todas las clases tienen al menos un constructor. Si una clase no declara explícitamente ninguna, ×
// método 1
el compilador de Java proporciona automáticamente un constructor sin argumentos, también llamado
“constructor default”. Este constructor predeterminado llama al constructor sin argumentos del padre de la
public String getNombre()
clase (ya que contiene solo una declaración, es decir super ();), o el constructor de la clase Object si la clase
{
no tiene otro padre (ya que la clase Object es padre de todas las clases ya sea directa o indirectamente)
return nombre;
// método 2
{
Hay cuatro formas de crear objetos en java. En pocas palabras, solo hay una forma (mediante el uso de la
return raza;
palabra clave ), y el resto internamente utiliza una nueva palabra clave.
}
Usar palabra clave (keyword) new: es la forma más común y general de crear objetos en Java.
// método 3
return edad;
// creando un objeto de clase Test
}
Test t = new Test ();
// método 4
Usando el método Class.forName (String className): hay una clase predefinida en el paquete
public String getColor()
java.lang con el nombre Class. El método forName (String className) devuelve el objeto Class asociado
{
con con el nombre de la clase. Tenemos que dar el nombre completo para una clase. Al llamar al
return color;
método new Instance() en este objeto Class, se devuelve una nueva instancia de la clase con el nombre
}
de cadena proporcionado.
@Override
","+ this.getColor());
Test t2 = (Test)t1.clone(); {
En el sistema de herencia, usamos una variable de referencia de clase primaria para almacenar un objeto de
subclase. En este caso, podemos cambiar a diferentes objetos de subclase usando la misma variable
referenciada.
class Animal {}
7. Objetos anónimos
Los objetos anónimos son los objetos que se instancian pero no se almacenan en una variable de referencia.
class Sobrecarga{
En general, para sobrecargar un método, simplemente declare versiones diferentes de él. El compilador se void demoSobrec(){
ocupa del resto. Debe observar una restricción importante: el tipo y/o el número de parámetros de cada System.out.println("Sin parámetros\n");
método sobrecargado debe diferir. No es suficiente que dos métodos difieran solo en sus tipos de devolución. }
Los tipos de devolución no proporcionan información suficiente en todos los casos para que Java decida × void demoSobrec(int a){
Por supuesto, los métodos sobrecargados también pueden diferir en sus tipos de devolución. Cuando se llama a
un método sobrecargado, se ejecuta la versión del método cuyos parámetros coinciden con los argumentos. //Sobrecargando demoSobrec para dos parámetros int
Aquí hay un ejemplo simple que ilustra la sobrecarga de métodos: int demoSobrec(int a, int b){
return a+b;
return a+b;
class DemoSobrecarga{
int sumaint;
double sumadouble;
sc.demoSobrec();
sc.demoSobrec(2);
sumaint=sc.demoSobrec(4,6);
sumadouble=sc.demoSobrec(1.1,2.2);
Salida:
// Conversiones automáticas de tipo
// en métodos sobrecargados
ⓘ class Sobrecarga{
void mitipo (int x){
Sin parámetros
System.out.println("Mi tipo (int): "+x);
Un parámetro: 2
void mitipo(double x){
Dos parámetros: 4, 6
System.out.println("Mi tipo (double): "+x);
class DemoSobrecarga{
Como puede ver, está sobrecargado cuatro veces. La primera versión no toma parámetros, la segunda toma un public static void main(String[] args) {
parámetro entero, la tercera toma dos parámetros enteros (int), y la cuarta toma dos parámetros double. Sobrecarga sc= new Sobrecarga();
Observe que las primeras dos versiones de ovlDemo() no devuelven nada, y las otras dos devuelven un valor. int i=10;
Esto es perfectamente válido, pero tal como se explicó, la sobrecarga no se ve afectada en un sentido u otro por double d= 10.1;
el tipo de devolución de un método. Por lo tanto, intentar utilizar las dos versiones siguientes de provocará un
error:
byte b= 99;
short s=10;
}
sc.mitipo(i);
sc.mitipo(d);
return a;
sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)
Salida:
La diferencia en sus tipos de devolución es insuficiente para el propósitos de sobrecarga.
Mi tipo (int): 10
Mi tipo (double): 10.1
Mi tipo (int): 99
Como recordará anteriormente en Conversión de tipos de datos, Java proporciona ciertas conversiones de tipo En este ejemplo, sólo dos versiones de están definidos: uno que tiene un parámetro de tipo int y otro que tiene
automáticas. Estas conversiones también se aplican a los parámetros de métodos sobrecargados. Por un tipo double. Sin embargo, es posible pasar un valor de tipo byte, short, o float a . En el caso de byte y short,
ejemplo, considere lo siguiente: Java automáticamente convierte a int. Así, mitipo(int) se invoca. En el caso de la float, el valor se convierte
a double y mitipo(double) es llamado.
Es importante entender, sin embargo, que la conversión automática sólo se aplican si no hay ninguna
coincidencia directa entre un parámetro y argumento. Por ejemplo, aquí está el programa anterior con la adición
de una versión de f ( ), que especifica un parámetro byte:
Para comprender cómo, considere lo siguiente: En los lenguajes que no admiten la sobrecarga de métodos, a
class Sobrecarga{ cada método se le debe asignar un nombre único. Sin embargo, frecuentemente querrá implementar
esencialmente el mismo método para diferentes tipos de datos.
// Agrego mitipo(byte)
debe tener su propio nombre, aunque las tres funciones hacen esencialmente lo mismo.
System.out.println("Mi tipo (int): "+x);
Esto hace que la situación sea más compleja, conceptualmente, de lo que realmente es. Aunque el concepto
}
subyacente de cada función es el mismo, todavía tiene tres nombres para recordar. Esta situación no ocurre en
Java, porque cada método de valor absoluto puede usar el mismo nombre. De hecho, la biblioteca de clases
void mitipo(double x){
estándar de Java incluye un método de valor absoluto, llamado abs(). Este método está sobrecargado por la
System.out.println("Mi tipo (double): "+x);
clase Math de Java para manejar todos los tipos numéricos. Java determina qué versión de abs() llamar en
}
función del tipo de argumento.
4. Preguntas Frecuentes
class DemoSobrecarga{
En Java, una firma es el nombre de un método más su lista de parámetros. Por lo tanto, para fines de
int i=10; sobrecarga, no hay dos métodos dentro de la misma clase que puedan tener la misma firma. Tenga en
double d= 10.1;
cuenta que una firma no incluye el tipo de devolución, ya que Java no lo utiliza para la resolución de
sobrecarga.
byte b= 99;
short s=10;
float f=11.5F;
¿Podemos sobrecargar los métodos estáticos?
sc.mitipo(i);
La respuesta es ‘Sí’. Podemos tener dos o más métodos estáticos con el mismo nombre, pero se
diferencian en los parámetros de entrada.
sc.mitipo(d);
¿Podemos sobrecargar los métodos que difieren solo por palabra clave static?
sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)
Overloading significa que un mismo método tiene diferentes firmas. Overriding es el mismo método,
Mi tipo (int): 10 misma firma pero diferentes clases conectadas a través de la herencia. La sobrecarga es un ejemplo
Mi tipo (double): 10.1
de polimorfismo en tiempo de compilación y la sobreescritura es un ejemplo de polimorfismo en tiempo
de ejecución.
Mi tipo (byte): 99
Mi tipo (int): 10
Mi tipo (double): 11.5
¿Podemos sobrecargar main() en Java?
En esta versión, ya que hay una versión de mitipo() que toma un byte de argumento, cuando mitipo() se llama Al igual que otros métodos estáticos, sí podemos sobrecargar main() en Java.
con un byte de argumento, mitipo(byte) se invoca y la conversión automática a int no se produce.
// El método main()
Tenemos un Auto ( car ), tiene muchas características. Los abstraemos, sólo nos interesan dos parámetros: la
// Sobrecargando el método main()
velocidad actual ( speed ) y la velocidad máxima ( maxSpeed ). En el mundo de la programación orientada a objetos,
este enfoque se llama abstracción. ¿Qué comportamiento esperamos de un Auto? Sólo dos: empezar a moverse
public static void main(String arg1) {
}
public class Car {
} void start(){}
void stop(){}
Salida: }
Aquí hemos descrito la plantilla del futuro objeto – una clase. Tiene dos variables de estado, speed y maxSpeed , y
Hola Javeros (desde el main)
dos métodos que describen el comportamiento del objeto.
Hola, Java
Hola, Java desde Cero, Sobrecarga de métodos Ahora la aplicación necesita ejecutarse, para ello Java necesita decirnos dónde está el punto de entrada a la
misma. Existe una convención especial para ello: hay que añadir un método a cualquier descripción de objeto:
Cuando sobrecarga un método, cada versión de ese método puede realizar cualquier actividad que desee. No }
hay ninguna regla que establezca que los métodos sobrecargados deben relacionarse entre sí. Sin embargo,
desde un punto de vista estilístico, la sobrecarga de métodos implica una relación. Exactamente el código que especifiquemos en él comenzará a ejecutarse.
Por ejemplo, podría usar el nombre sqr para crear métodos que devuelvan el cuadrado de un entero y la raíz
cuadrada de un valor de coma flotante. Pero estas dos operaciones son fundamentalmente diferentes. Aplicar la java Car
sobrecarga de métodos de esta manera frustra su propósito original. En la práctica, debe sobrecargar solo
operaciones estrechamente relacionadas.
O, mucho más fácil, simplemente pulsa la flecha verde junto al método y el editor (IntelliJ IDEA Community):
Ten en cuenta que cada archivo sólo puede contener una clase pública. Es decir, la palabra clave public junto
con la palabra class .
Imporante
La palabra clave public es un modificador de acceso. Define el nivel de accesibilidad de esta
clase/método/variable desde otras partes del programa.
El nombre del archivo debe coincidir con el nombre de la clase, distinguir entre mayúsculas y minúsculas y
tener la extensión .java . La palabra clave static indica al compilador que el método/variable pertenece a un
modelo de objeto, es decir, a una clase y no a un objeto específico.
Paquetes en Java
Cabe destacar que las clases suelen tener el mismo nombre en los programas, por lo que se sugirió ponerlas en
carpetas para que no haya conflicto de nombres. La carpeta donde se encuentra la clase se especifica en la parte
superior del archivo:
Nuestra aplicación se ejecuta, pero no ocurre nada porque no hemos añadido ninguna lógica al método. Vamos a
añadir una salida de texto simple a la consola:
método se obtendrá algún entero de tipo int . En la programación orientada a objetos, esta técnica se void start() {
llama encapsulación – cuando un objeto genera internamente algún resultado basado en su estado, sin que el System.out.println("Empezar a conducir");
void stop() {
System.out.println("Detenerse");
myCar.start();
myCar.stop();
Continuemos con el código presentado anteriormente. Empecemos por la más sencilla. Si queremos añadir alguna
explicación/comentario al código, podemos insertar dos barras inclinadas ( // ) en cualquier línea y todo el texto
que haya después de ellas será descartado al compilar el programa, pero al visualizar el código fuente será visible.
Creación de Objetos
A medida que los ordenadores fueron evolucionando gradualmente, en diferentes etapas de su vida podían
almacenar un número que no era mayor que el dígito del procesador en el que funcionaban.
Por eso ha aparecido esta tabla de bits con diferentes números. En nuestro caso, utilizaremos números de
tipo int , que pueden describirse con 32 bits en la memoria del ordenador. Es decir, nuestros números estarán
entre -2.147.483.648 (-2^31) y 2.147.483.647 (2^31-1).
Constructores de Objetos
Ahora queremos que nuestro comportamiento dependa también del estado interno del objeto. Para ello, tenemos
que definirlo de alguna manera. Veamos cómo se puede hacer esto.
int speed;
int maxSpeed;
this.speed = speed;
this.maxSpeed = maxSpeed;
void start() {
System.out.println("Empezar a conducir");
System.out.println(speed);
System.out.println(maxSpeed);
Los ordenadores trabajan principalmente con números, por lo que se han acuñado varias palabras clave para
denotar diferentes tipos de datos, también conocidos como tipos de datos primitivos: Car myCar = new Car(100, 500);
myCar.start();
myCar.stop();
Además, las strings pueden sumarse entre sí o con otros tipos primitivos, pero no restarse, dividirse, etc:
Añade estas líneas a nuestro código y verás que todo funciona bien. Pero, de nuevo, esta excepción se hace sólo
para una clase – String, porque las strings se utilizan muy a menudo.
Operadores en Java
Ya que hemos mencionado a los operadores, veamos qué ofrece Java.
Un operador unario es un operador que sólo requiere un operando, o variable, y que suele realizar operaciones
sencillas.
myCar = null;
Operador Descripción Ejemplo
Hemos equiparado nuestro puntero al objeto con la palabra clave null , que indica a la máquina virtual que este
puntero ya no puede ser utilizado para acceder al objeto, es decir, llamar a myCar.start( ); provocará un error. + Suma var i = 5; var k = 6; System.out.println(i + k)
¿Qué ocurre con el objeto que hemos creado? La máquina virtual de Java ejecuta un recolector de basura, que
detectará que este objeto vive sin ninguna referencia y lo borrará de la memoria, es decir, lo borrará de la RAM. – Resta var i = 5; var k = 6; System.out.println(i – k)
Pero, esto no funciona con los tipos primitivos: * Multiplicación var i = 5; var k = 6; System.out.println(i * k)
También hay que tener en cuenta que las cadenas/strings también son clases, pero hay cambios significativos en
el lenguaje para ellas.
Si estamos escribiendo una expresión matemática compleja, es mejor utilizar paréntesis: Además, si la condición devuelve false podemos utilizar la palabra clave else para añadir otro bloque de código
que se ejecute en ese caso:
var x = 5 * (6 – 8);
void setSpeed(int speed) {
Me gustaría cerrar la sección de operadores con una tabla de operadores condicionales, cuyo resultado es if (speed < maxSpeed) {
else {
var i = 5; var k = 6;
== Comparación de la igualdad }
System.out.println(i == k)
Operador or (o). Al menos una parte debe ser System.out.println(false || public static void main(String[] args) {
myCar.start();
i++;
Hemos conocido los operadores más populares en Java, ahora es el momento de utilizarlos. }
}
Queremos que nuestro Auto pueda cambiar su comportamiento, es decir, cambiar la velocidad actual que
establecimos al crearlo.
En este caso, creamos una variable primitiva i inicialmente igual a 0 . En el bucle tenemos la condición de que
sea menor que 10; si no lo es, el código entre corchetes no se ejecutará. En ellos aumentamos el valor de i en
Añadamos un nuevo método que haga esto: uno, si no lo hiciéramos, el bucle se ejecutaría eternamente. Ejecuta el programa y ve lo que se muestra y cuántas
veces.
void setSpeed(int speed){
Para separar esas lógicas de bucle de nuestro código se creó un bucle for .
this.speed = speed;
}
Encuentra las diferencias:
Pero no queremos que nadie que utilice nuestra clase pueda ajustar la velocidad por encima del máximo.
for (var i = 0; i < 10; i++) {
Expresiones Condicionales }
myCar.start();
Para imponer cualquier restricción a una variable, tenemos que realizar una comprobación, y para ello tenemos Entre paréntesis, creamos un contador, pasamos la condición del bucle y una “fórmula” para saber qué hacer con
que utilizar una expresión condicional if : el contador en cada iteración. Estarás de acuerdo en que así el código parece más compacto y la lógica de control
del bucle no se mezcla con nuestra lógica.
this.speed = speed;
for( ; ; ) {
System.out.println("Hello World");
}
}
Entre paréntesis ponemos la condición que debe devolver true o false, y entre llaves añadimos el código que se
ejecutará si la condición es verdadera ( true ). No hay manera de salir de ella, excepto terminando la aplicación con el sistema operativo. Podemos terminarlo
utilizando la palabra clave break :
Lo más importante es que no hemos fijado el tamaño de nuestra colección. Esto se debe a que te permite añadir
for( ; ; ) {
tantos elementos como la memoria de tu ordenador pueda contener.
System.out.println("Hello World");
break;
Una colección de tipo HashSet (conjunto) no permitirá dos valores idénticos, compara las conclusiones:
}
El mensaje se mostrará en la consola y el bucle se detendrá en este punto. var garage = new HashSet<Car>();
garage.add(myCar);
garage.add(myCar2);
En nuestro proyecto sólo hemos creado un Auto, ahora vamos a crear varios y ponerlos en algún tipo de almacén.
for (Car car : garage) {
car.start();
garage[0] = myCar;
Además de las listas, también es popular la colección Map , que permite asignar claves a los objetos y luego
for (Car car : garage) {
}
var myCar = new Car(100, 500);
En el ejemplo anterior, creamos dos Autos, luego creamos un array de punteros a objetos de la clase Car con var myCar2 = new Car(10, 50);
tamaño 2 y pusimos punteros a nuestros objetos en él. Como puedes ver, el recuento de las celdas de la matriz var garage = new HashMap<String, Car>();
comienza con 0. Después, utilizamos una modificación especial del bucle for para arrays y colecciones, que nos
permite recorrer todos los elementos y hacer algo de lógica con ellos. garage.put("Mi auto", myCar);
Así, ahora tenemos un objeto que puede almacenar varios punteros a otros objetos, pero no es conveniente
trabajar con arrays. Tenemos que saber de antemano el tamaño exacto y en qué celdas tenemos que escribir. Por
garage.get("Mi segundo auto").start();
eso, las colecciones son ahora el método más popular de almacenamiento de datos.
Reescribamos nuestro código utilizando colecciones: He especificado una cadena como clave, una práctica muy común. Y puse mis dos objetos en la colección. Luego
usé la llave para obtener mi objeto y llamar a su método.
garage.add(myCar);
Excepciones
garage.add(myCar2);
¿Qué pasaría si escribiera mi consulta de la siguiente manera?
for (Car car : garage) {
car.start();
} garage.get("segundo auto").start();
Como puedes ver, el código no ha cambiado mucho, pero esas torpes entradas de punteros en celdas específicas Verás lo siguiente en la consola:
han desaparecido. Ahora todo se guarda automáticamente.
Exception in thread "main" java.lang.NullPointerException
var garage = new ArrayList<Car>(); Se ha producido una situación excepcional y el programa se ha interrumpido. Porque el
método get devolvía null , lo que ya hemos comentado antes. Así que no teníamos un objeto sobre el que
¿Qué significa esto? Aquí estamos diciendo que usaremos una colección basada en array y que nuestra colección pudiéramos llamar al método. El bloque try/catch se inventó para evitar estas situaciones. Veamos cómo puede
contendrá objetos como Car . ayudar a resolver nuestro problema:
try {
Aprende sobre estructuras condicionales en Java: if, if-else, switch, break, continue, jump. Muchos ejemplos
garage.get("segundo auto").start();
con explicación para que aprendas de manera rápida.
}catch (NullPointerException exception){
if
if-else
nested-if
if-else-if
switch-case
jump – break, continue, return
Estas declaraciones le permiten controlar el flujo de la ejecución de su programa en función de condiciones
conocidas solo durante el tiempo de ejecución.
Table de Contenido
1. if
2. if-else
3. Anidación-if
4. Escalera if-else-if
5. switch-case
6. jump o saltos
6.1. break
6.2. Continue
6.3. Return
1. if
La sentencia if es la declaración de toma de decisiones más simple. Se usa para decidir si una determinada
declaración o bloque de enunciados se ejecutará o no; es decir, si una determinada condición es verdadera
(true), se ejecutará un bloque de enunciado y, de ser falsa (false), no.
Sintaxis:
if (condición)
// la condición es verdadera
Aquí, la condición después de la evaluación será verdadera o falsa. if acepta valores booleanos: si el valor es
verdadero, ejecutará el bloque de instrucciones debajo de él. OJO: Si no proporcionamos las llaves ‘{‘ y ‘}’
después del if (condición), entonces de forma predeterminada la sentencia if considerará que la declaración
inmediata está dentro de su bloque.
Por ejemplo:
if (condicion)
if (condición)
declaracion1; {
// la condición es verdadera
// de su bloque. {
Ejemplo:
class IfDemo
{
class IfElseDemo
int i = 10;
{
public static void main(String args[])
if (i > 15)
{
}
System.out.println("Soy mayor de 15");
} }
}
Salida:
Salida:
Soy mayor de 15
3. Anidación-if
Una if anidado (nested-if) es una declaración if que se deriva de otro if o else. Las declaraciones if anidadas
significan una instrucción if dentro de una declaración if. Sí, Java nos permite anidar las
declaraciones if con if, es decir, podemos colocar una instrucción if dentro de otra instrucción if.
Sintaxis:
ⓘ
if (condicion1)
No estoy en IF {
2. if-else if (condition2)
La declaración if solo nos dice que, si una condición es verdadera ejecutará un bloque de instrucciones y si la }
condición es falsa, no lo hará. Pero, ¿y si queremos hacer otra cosa cuando la condición sea falsa? Aquí viene }
la declaración else. Podemos usar la instrucción else con la instrucción if para ejecutar un bloque de código
cuando la condición es falsa. Ejemplo:
Sintaxis:
class NestedIfDemo
class ifelseifDemo
{
{
{
{
int i = 10;
int i = 20;
if (i == 10)
if (i == 10)
{
System.out.println("i es 10");
// Primera declaración if
else if (i == 15)
if (i < 15)
System.out.println("i es 15");
System.out.println("i es 20");
// Declaración if anidada
else
// es verdad
}
if (i < 12)
}
System.out.println("yo también soy menor que 12");
else
Salida:
System.out.println("soy mayor que 15");
}
i es 20
}
Salida:
5. switch-case
La instrucción switch es una declaración de bifurcación de múltiples vías (selección múltiple). Proporciona una
soy menor que 15
forma sencilla de enviar la ejecución a diferentes partes del código en función del valor de la expresión.
yo soy menor que 12
Sintaxis:
4. Escalera if-else-if
switch (expresión)
Aquí, un usuario puede decidir entre múltiples opciones. Las sentencias if se ejecutan desde arriba hacia abajo.
case valor1:
Tan pronto como una de las condiciones que controlan el if sea verdadera, se ejecuta la instrucción asociada con
ese if, y el resto de la escalera se pasa por alto. Si ninguna de las condiciones es verdadera, se ejecutará la declaracion1;
case value2:
declaracion2;
if (condición)
break;
declaración; .
else if (condición)
.
.
declaracionN;
.
break;
declaración
default:
else ; declaracionDefault;
}
Ejemplo:
La expresión puede ser de tipo byte, short, int, char o una enumeración. A partir de JDK7, la expresión
también puede ser de tipo String.
Los valores duplicados de case no están permitidos.
La declaración predeterminada es opcional.
La declaración de interrupción se usa dentro del switch para finalizar una secuencia de instrucción.
La declaración es opcional. Si se omite, la ejecución continuará en el siguiente case.
Ejemplo:
// Java program to illustrate switch-case
class SwitchCaseDemo
{
Nota: break, cuando se utiliza dentro de un conjunto de bucles anidados, solo saldrá del bucle más
public static void main(String args[])
interno.
{
int i = 9;
switch (i)
case 0:
System.out.println("i es cero.");
break;
class BreakLoopDemo
case 1:
System.out.println("i es uno.");
break;
case 2:
System.out.println("i es dos.");
break;
default:
if (i == 5)
break;
}
System.out.println("i: " + i);
Salida:
System.out.println("Bucle completo.");
i es mayor que 2. }
Salida:
6. jump o saltos
i: 0
Java admite tres declaraciones de salto: break, continue y return. Estas tres declaraciones transfieren el i: 1
i: 3
6.1. break i: 4
Bucle completo.
Utilizando el break, podemos forzar la terminación inmediata de un bucle, evitando la expresión condicional y
declaracion1;
declaracion3;
Ahora, la instrucción break se puede utilizar para saltar fuera del bloque objetivo. Así:
Nota: No puede romper ninguna etiqueta que no esté definida para un bloque envolvente. class ContinueDemo
Ejemplo: {
// Si el número es par
// omitir y continuar
if (i%2 == 0)
class BreakLabelDemo
continue;
boolean t = true;
// etiqueta first
}
first:
Salida:
// Declaración de la etiqueta second
second:
{
1 3 5 7 9
third:
{
// Antes de break
6.3. Return
System.out.println("Antes de la sentencia break");
la declaración return se usa para regresar explícitamente de un método. Es decir, hace que un control de
// break tomará el control de
programa se transfiera nuevamente a quién llama del método.
// la etiqueta second
if (t)
Ejemplo:
break second;
System.out.println("Esto no se ejecutará.");
}
class Return
System.out.println("Esto no se ejecutará.");
// Tercer bloque
boolean t = true;
System.out.println("Antes de return.");
if (t)
}
return;
// después de return
A veces es útil forzar una iteración temprana de un bucle. Es decir, es posible que desee continuar ejecutando el
bucle, pero deje de procesar el resto del código (en su cuerpo) para esta iteración en particular. Esto es, en Antes de return.
efecto, un goto pasando del cuerpo del bucle, al final del bucle. La instrucción continue realiza tal acción.
Hasta aquí hemos visto las estructuras condicionales de Java: if, if-else, switch, break, continue, jump.
Ejemplo: Cualquier duda, aclaración o aporte, lo puede hacer en los comentarios
Aprenda sobre la estructura repetitiva en Java. Conceptos y ejemplos sobre bucles for, while, do while para
aprender Java en instantes.
Java proporciona tres formas de ejecutar los bucles. Si bien todas las formas proporcionan una funcionalidad
básica similar, difieren en su sintaxis y el tiempo de comprobación de la condición. Veamos las 3 formas:
Table de Contenido
1. Bucle while
2. Bucle for
2.1. Bucle for mejorado (for each)
3. Bucle do while
4. Errores de bucles: Bucle infinito
1. Bucle while
Un bucle while es una sentencia de control de flujo que permite que el código se ejecute repetidamente en
función de una condición booleana dada. El bucle while se puede considerar como una instrucción if repetitiva.
Sintaxis:
El while comienza con la verificación de la condición. Si se evalúa como verdadero, las instrucciones del
cuerpo del bucle se ejecutan; de lo contrario, se ejecuta la primera instrucción que le sigue al bucle. Por
esta razón, también se llama bucle de control de entrada.
Una vez que la condición se evalúa como verdadera, se ejecutan las instrucciones en el cuerpo del bucle.
Normalmente, las declaraciones contienen un valor de actualización para la variable que se procesa para
la siguiente iteración.
Cuando la condición se vuelve falsa, el ciclo finaliza y marca el final de su ciclo de vida.
Ejemplo:
for (condición de inicialización, condición de prueba;
incremento / decremento)
class whileLoopDemo
declaracion(es)
{
}
public static void main(String args[])
int x = 1;
while (x <= 4)
x++;
Salida:
Valor de x: 1
Diagrama de Flujo: Bucle for en Java
Valor de x: 2
Valor de x: 3
Valor de x: 4 1. Condición de inicialización: Aquí, inicializamos la variable en uso. Marca el inicio de un ciclo for. Se puede
usar una variable ya declarada o se puede declarar una variable, solo local para el bucle.
2. Bucle for 2. Condición de prueba: se usa para probar la condición de salida de un bucle. Debe devolver un valor
booleano. También es un bucle de control de entrada cuando se verifica la condición antes de la ejecución de
las instrucciones de bucle.
El bucle for proporciona una forma concisa de escribir la estructura de bucle. A diferencia de un ciclo while, una
sentencia for consume la inicialización, la condición y el incremento/decremento en una línea, proporcionando 3. Ejecución de instrucción: una vez que la condición se evalúa como verdadera, se ejecutan las
así una estructura de bucle más corta y fácil de depurar. instrucciones en el cuerpo del bucle.
5. Terminación de bucle: cuando la condición se vuelve falsa, el bucle termina marcando el final de su ciclo de
vida.
Ejemplo:
class forLoopDemo
{
Salida:
Valor de x: 2
Valor de x: 3
Nota para leer
Valor de x: 4
Bucle for en Java (Puntos importantes)
Java también incluye otra versión del bucle for introducido en Java 5. La mejora del bucle for proporciona una
forma más sencilla de iterar a través de los elementos de una colección o matriz. Es inflexible y debe usarse solo
cuando existe la necesidad de recorrer los elementos de forma secuencial sin conocer el índice del elemento
3. Bucle do while
procesado actualmente.
El bucle do while es similar al while con la única diferencia de que comprueba la condición después de ejecutar
Sintaxis: las instrucciones, y por lo tanto es un ejemplo de Exit Control Loop (Salir del bloque de control).
declaraciones)
Tomemos un ejemplo para demostrar cómo se puede utilizar “enhanced for” para simplificar el trabajo.
Supongamos que hay una matriz de nombres y queremos imprimir todos los nombres en esa matriz. Veamos la
diferencia con estos dos ejemplos:
{
2. Después de la ejecución de los enunciados, y la actualización del valor de la variable, la condición se verifica
System.out.println(x);
para el valor verdadero o falso. Si se evalúa como verdadero, comienza la siguiente iteración del ciclo.
}
3. Cuando la condición se vuelve falsa, el ciclo finaliza y marca el final de su ciclo de vida.
/*bucle for para la misma función
4. Es importante tener en cuenta que el bucle do-while ejecutará sus declaraciones al menos una vez antes
for (int i = 0; i < array.length; i++)
de que se verifique cualquier condición, y por lo tanto es un ejemplo de bucle de control de salida.
{
System.out.println(array);
Ejemplo:
}
*/
Salida:
Ron
Harry
Hermoine
Otro inconveniente es que puede estar agregando algo en su objeto de colección a través de un bucle y
// Programa Java para ilustrar el bucle do-while
puede quedarse sin memoria. Si intenta ejecutar el siguiente programa, después de un tiempo, se producirá
class dowhileloopDemo
una excepción de falta de memoria.
{
{
//Programa Java para la excepción de falta de memoria.
int x = 21;
import java.util.ArrayList;
do
public class Integer1
{
{
x++;
for (int i = 0; i < Integer.MAX_VALUE; i++)
}
{
}
}
} }
}
Salida:
Salida:
Valor de x: 21
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
Uno de los errores más comunes al implementar cualquier tipo de bucle es que nunca puede salir, es decir, el at java.util.ArrayList.add(Unknown Source)
bucle se ejecuta durante un tiempo infinito. Esto sucede cuando la condición falla por alguna razón. at article.Integer1.main(Integer1.java:9)
Ejemplo:
Si tienes alguna duda en la implementación de bucles en Java, me comentas
for (int i = 5; i != 0; i -= 2)
System.out.println(i);
int x = 5;
// no se proporciona
while (x == 5)
System.out.println("En el bucle");
}
En Java, se pueden inicializar múltiples variables en el bloque de inicialización del bucle for, independientemente
Veamos algunos puntos importantes sobre el bucle for en Java. Inicialización de múltiples variables, re-
de si lo usa en el bucle o no.
declaración de una variable, entre otras cosas.
// en el bloque de inicio
//Cuerpo
}
public static void main(String[] args)
Veamos algunos ejemplos básicos de cómo usar el bucle for y las trampas comunes al usarlo:
int x = 2;
Table de Contenido {
4. Las variables declaradas en el bloque de inicialización deben ser del mismo tipo }
Salida:
1. Proporcionar expresión en for es obligatorio
0
El bucle for debe consistir en una expresión válida en la declaración, sino puede conducir a un bucle infinito. La 1
declaración es similar a 2
Ejemplo: 4
// bucle infinito
10
public class Example1
En el código anterior, hay una variación simple en el bucle for. Dos variables son declaradas e inicializadas en el
public static void main(String[] args)
bloque de inicialización. La variable “z” no se está utilizando. Además, los otros dos componentes contienen una
{
variable adicional. Entonces, se puede ver que los bloques pueden incluir variables adicionales que no pueden
for( ; ; )
ser referenciadas entre sí.
{
}
3. Redeclaración de una variable en el bloque de
inicialización
}
Supongamos que una inicialización de variable ya está declarada como un entero. ¿Podemos volver a declararlo
Salida: en un bucle for como otro tipo de dato? No, mira el ejemplo:
Ejemplo:
Este es un ciclo infinito
...
// en el bloque de inicialización
// en el bloque de inicialización
{
{
{
{
// x es integer
// x es integer
int x = 0;
int x = 0;
long y = 10;
{
{
}
}
}
}
} }
Salida: Salida:
1 2 3 4
Ejemplo:
ⓘ
// Programa Java para ilustrar
Aquí, x ya se inicializó a cero como número entero y se vuelve a declarar en el bucle con el tipo de datos long. {
Pero este problema se puede solucionar modificando ligeramente el código. Aquí, las variables x y y se declaran {
// int x;
Ejemplo:
}
5. Las variables en el bucle solo son accesibles en 1. switch case en Java
su interior
La instrucción switch es una instrucción de múltiples vías. Proporciona una forma sencilla de enviar la ejecución
a diferentes partes del código en función del valor de la expresión. Básicamente, la expresión puede ser tipos de
Las variables declaradas en el bloque de inicialización solo se puede acceder dentro del bucle. Para más
datos primitivos byte, short, char e int. A partir de JDK7, también funciona con tipos enumerados (Enum en
información sobre el alcance o ámbito de las variables, consulte aquí.
java), la clase String y las clases Wrapper .
Ejemplo:
Sintaxis de Switch-case:
// declaración de switch
switch(expresión)
// dentro del bucle
// declaración case
case valor1 :
// Declaraciones
case valor2 :
// Declaraciones
System.out.println(x);
// debajo se encuentra la declaración predeterminada, que se usa cuando ninguno de los casos e
}
}
default :
// Declaraciones
Salida: }
En el ejemplo anterior, la variable x no es accesible fuera del bucle. La declaración que se comenta da error de
compilación.
Considere el siguiente programa java, declara un llamado day cuyo valor representa un día (1-7). El código
muestra el nombre del día, basado en el valor del día, usando la declaración switch.
int day = 5;
String dayString;
switch (day)
break;
break;
break;
break;
break;
break;
break;
break;
System.out.println(dayString);
Salida:
String dayType;
String dayString;
// programa de Java para demostrar
// declaracines switch case anidadas
switch (day)
public class Test
{
{
break;
{
break;
int year = 2;
break;
switch(year)
break;
case 1 :
break;
break;
break;
switch (Branch) // switch anidado
}
System.out.println("Cursos electivos : Machine Learning, Big Data");
break;
switch (day)
{
case "ECE":
case 1:
case 2:
default:
case 3:
System.out.println("Cursos electivos : Ingenieria de Software");
case 4:
}
case 5:
}
break;
}
case 6:
case 7:
Salida:
dayType = "Fin de semana";
break;
}
Desde JDK 7, podemos usar una cadena literal/constante para controlar una declaración switch, lo cual no es
} posible en C/C++. Usar un modificador basado en cadena/string es una mejora con respecto al uso de la
secuencia equivalente if/else.
Puntos importantes: ⓘ
Operación costosa: el “switching” de strings puede ser más costosa en términos de ejecución que
el switching de tipos de datos primitivos. Por lo tanto, es mejor activar el switch con strings solo en casos
de que los datos de control ya estén en forma de cadena.
String no debe ser NULL: asegúrese de que la expresión en cualquier instrucción switch no sea nula
mientras se trabaja con cadenas para evitar que una NullPointerException sea lanzada en tiempo de
ejecución.
Case Sensitive – mayúsculas/minúsculas: la instrucción switch compara el objeto String en su
expresión con las expresiones asociadas con cada etiqueta de case como si estuviera usando el
método String.equals; en consecuencia, la comparación de objetos String en sentencias switch es
sensible a mayúsculas y minúsculas.
Mejor que if-else: el compilador Java genera bytecode generalmente más eficiente a partir de sentencias
switch que usan objetos String que de sentencias if-else anidadas.
Ejemplo:
switch(str)
case "uno":
System.out.println("uno");
break;
case "dos":
System.out.println("dos");
break;
case "tres":
System.out.println("tres");
break;
default:
System.out.println("no coincide");
Salida:
dos
No existe un programador que no tenga problemas con null. Todos los lenguajes de programación lo incluyen. public class Test
Mira estos puntos interesantes de null en Java! {
En Java, null está asociado a java.lang.NullPointerException. Como es una clase en el paquete java.lang, se public static void main(String args[])
invoca cuando intentamos realizar algunas operaciones con o sin null y, a veces, ni siquiera sabemos dónde ha
{
sucedido.
// imprimira nulo;
A continuación se detallan algunos puntos importantes sobre null en Java que todo programador de Java debe
saber: }
null es literal en Java y porque las palabras clave distinguen entre mayúsculas y minúsculas en java, no
podemos escribir NULL o 0. String str = null;
{
Double dbl = null;
String myStr = (String) null;
}
Integer myItr = (Integer) null;
4. Autoboxing y unboxing
^
variable NULL
Durante las operaciones de auto-boxing y unboxing, el compilador simplemente arroja un error de excepción
class Test
Nullpointer si se asigna un valor nulo al tipo de datos en recuadro primitivo.
1 error
false
true
//Un número entero puede ser nulo, así que esto está bien
Como los métodos estáticos están vinculados mediante el enlace estático, no lanzarán NullPointerException.
Integer i = null;
}
public static void main(String args[])
} {
Salida: obj.staticMethod();
obj.nonStaticMethod();
at Test.main
private static void staticMethod()
El operador instanceof de Java se usa para probar si el objeto es una instancia del tipo especificado (clase, }
subclase o interfaz). En tiempo de ejecución, el resultado del operador instanceof es verdadero si el valor de la
Esta es una propiedad importante de la operación instanceof, que lo hace útil para las verificaciones de //Can not be called by null reference
Ejemplo:
{
}
public static void main (String[] args) throws java.lang.Exception
{
Salida:
Integer i = null;
Integer j = 10;
at Test.main
//imprime false
{
Los métodos son subrutinas que manipulan los datos definidos por la clase y, en muchos casos, brindan
acceso a esos datos. En la mayoría de los casos, otras partes de tu programa interactuarán con una clase a
//return true;
través de sus métodos.
System.out.println(null==null);
Un método contiene una o más declaraciones. En un código Java bien escrito, cada método realiza solo una
//return false;
tarea. Cada método tiene un nombre, y es este el que se usa para llamar al método. En general, puede dar el
System.out.println(null!=null);
nombre que desee a un método cualquiera. Sin embargo, recuerde que main() está reservado para el método
que comienza ejecución de su programa. Además, no use las palabras clave de Java para nombres de métodos.
Aquí, tipo-retorno especifica el tipo de datos devueltos por el método. Puede ser cualquier tipo válido,
incluidos los tipos de clase que cree. Si el método no devuelve un valor, su tipo de devolución debe ser .
El nombre del método se especifica por nombre. Puede ser cualquier identificador legal que no sea el que
ya utilizan otros elementos dentro del alcance actual.
La lista de parámetros es una secuencia de tipos e identificadores separados por comas. Los parámetros
son esencialmente variables que reciben el valor de los argumentos pasados al método cuando se llama.
Si el método no tiene parámetros, la lista de parámetros estará vacía.
3. Ejemplos de Métodos
Agregar un método a la clase de Vehiculo
ⓘ
Anteriormente:
*/
class Vehiculo {
class Vehiculo {
int pasajeros; //números de pasajeros
}
//Mostrando el rango
class DemoVehiculo {
System.out.println("Con rango de "+ capacidad*mpg);
int rango;
minivan.pasajeros = 9;
minivan.capacidad = 15;
public static void main(String[] args) {
minivan.mpg = 20;
Vehiculo minivan = new Vehiculo();
}
//Asigando valores a los campos en minivan
} minivan.pasajeros=9;
minivan.capacidad=15;
minivan.mpg=20;
Como acabamos de explicar, los métodos de una clase suelen manipular y proporcionar acceso a los datos de la
clase. Con esto en mente, recuerde que en los ejemplos anteriores calculó el rango de un vehículo al multiplicar //Asigando valores a los campos en minivan
su tasa de consumo de combustible por su capacidad de combustible. Si bien es técnicamente correcto, esta no sportscar.pasajeros=10;
sportscar.mpg=30;
El cálculo del alcance de un vehículo es algo que se maneja mejor con la clase de vehículo en sí. El motivo de
esta conclusión es fácil de entender: el alcance de un vehículo depende de la capacidad del tanque de
combustible y la tasa de consumo de combustible, y ambas cantidades están encapsuladas por el vehículo. Al System.out.print("La Minivan puede llevar " +minivan.pasajeros +". ");
agregar un método al Vehículo que calcula el rango, está mejorando su estructura orientada a objetos. minivan.rango();
Para agregar un método al Vehículo, especifíquelo dentro de la declaración del Vehículo. Por ejemplo, la System.out.print("El Sportscar puede llevar " +minivan.pasajeros +". ");
siguiente versión de Vehiculo contiene un método llamado rango() que muestra el rango o alcance del vehículo. sportscar.rango();
//La línea termina con la llave de apertura del cuerpo del método. int i;
El cuerpo del rango() consiste únicamente en esta línea: if (i == 5) return; //Se detiene antes de llegar a 5
System.out.println(i);
//Esta declaración muestra el rango del vehículo multiplicando la capacidad del combustible por m }
//Dado que cada objeto de tipo Vehiculo tiene su propia copia de capacidad y mpg, cuando se llama
//a rango(), el cálculo de rango utiliza las copias del objeto que realiza la llamada de esas var Aquí, el bucle for solo se ejecutará de 0 a 5, porque una vez que sea igual a 5, el método retornará (Ojo, no
//El método rango() finaliza cuando se encuentra su llave de cierre.
devuelve sino que finaliza).. Es permisible tener múltiples instrucciones return en un método, especialmente
cuando hay dos o más rutas fuera de él. Por ejemplo:
//Esto hace que el control del programa se transfiera nuevamente a quién lo llama.
void miMetodo(){
A continuación, mira de cerca esta línea de código desde adentro de main(): // ...
if (hecho) return;
minivan.rango(); // ...
if (error) return;
Esta declaración invoca el método rango() en minivan. Es decir, llama a rango() relativo al objeto de minivan, // ...
utilizando el nombre del objeto seguido del operador de punto. Cuando se llama a un método, el control del }
programa se transfiere al método. Cuando el método finaliza, el control se transfiere de vuelta a quién lo
llama, y la ejecución se reanuda con la línea de código que sigue a la llamada.
Aquí, el método retorna si está hecho o si ocurre un error. Tenga cuidado, sin embargo, porque tener
demasiados puntos de salida en un método puede desestructurar tu código; así que evita usarlos casualmente.
En este caso, la llamada a minivan.rango() muestra el rango del vehículo definido por minivan. De manera Un método bien diseñado tiene puntos de salida bien definidos.
similar, la llamada a sportscar.rango() muestra el rango del vehículo definido por sportscar. Cada vez
que rango() se invoca, muestra el rango para el objeto especificado.
Recuerde: un método void puede retornar (regresa a quién lo llama) de una de las dos maneras: cuando ×
Hay algo muy importante para notar dentro del método rango(): las variables de instancia capacidad y mpg se alcanza su llave de cierre, o cuando se ejecuta una declaración return.
refieren directamente, sin precederlas con un nombre de objeto o el operador de punto. Cuando un método usa
una variable de instancia que está definida por su clase, lo hace directamente, sin referencia explícita a un
objeto y sin el uso del operador de punto. Esto es fácil de entender si lo piensas mejor.
6. Devolviendo un valor
Un método siempre se invoca en relación con algún objeto de su clase. Una vez que se ha producido esta
invocación, se conoce el objeto. Por lo tanto, dentro de un método, no hay necesidad de especificar el objeto por
segunda vez. Esto significa que capacidad y mpg dentro de rango() se refieren implícitamente a las copias de Aunque los métodos con un tipo de retorno void no son raros, la mayoría de los métodos devolverán un valor. De
esas variables encontradas en el objeto que invoca rango(). hecho, la capacidad de devolver un valor es una de las características más útiles de un método.
Los valores de retorno se utilizan para una variedad de propósitos en la programación. En algunos casos, el
5. Retornando de un Método valor de retorno contiene el resultado de algún cálculo. En otros casos, el valor de retorno puede simplemente
indicar éxito o falla. Y en otros, puede contener un código de estado. Cualquiera que sea el propósito, usar
valores de retorno de método es una parte integral de la programación de Java.
En general, hay dos condiciones que hacen que un método retorne:
Los métodos devuelven un valor a la rutina de llamada usando esta forma de devolución:
Primero, como lo muestra el método rango() en el ejemplo anterior, cuando se encuentra la llave de cierre
del método.
El segundo es cuando se ejecuta una declaración de retorno (return). return valor;
Hay dos formas de devolución: Aquí, valor es el valor devuelto. Esta forma de devolución se puede usar solo con métodos que tienen un tipo de
devolución no-void. Además, un método no-void debe devolver un valor utilizando esta forma de return.
Una cuando usa métodos con la palabra void (aquellos que no devuelven un valor) y otra para devolver
valores. Veremos la primera forma y luego pasaremos a retornar valores.
En un método , se puede causar la terminación inmediata de un método utilizando esta forma de devolución:
6.1. Uso de return en un método
Puede usar un valor de retorno para mejorar la implementación de rango(). En lugar de mostrar el rango, un
return; mejor enfoque es hacer que rango() calcule el rango y devuelva este valor. Una de las ventajas de este enfoque
es que puede usar el valor para otros cálculos.
Ejemplo: En el programa, observe que cuando se llama a rango(), se coloca en el lado derecho de una instrucción de
asignación. A la izquierda hay una variable que recibirá el valor devuelto por rango(). Por lo tanto, después de
El siguiente ejemplo modifica rango() para devolver el rango en lugar de mostrarlo. que se ejecuta, el rango del objeto minivan se almacena en el rango1.
Observe que rango() ahora tiene un tipo de retorno int. Esto significa que devolverá un valor entero a quién lo
//Usando return
llama. El tipo de devolución de un método es importante porque el tipo de datos devueltos por un método debe
ser compatible con el tipo de devolución especificado por el método.
class Vehiculo {
Por lo tanto, si desea que un método devuelva datos de tipo double, su tipo de return debe ser de ×
tipo double.
int mpg; //combustible consumido en millas por galon
System.out.println("La Minivan puede llevar " +minivan.pasajeros +". Con rango de: "+ minivan.ran
}
class RetornandoMetodo {
7. Métodos con Parámetros
public static void main(String[] args) {
Es posible pasar uno o más valores a un método cuando se llama al método. Recuerde que un valor pasado a
Vehiculo sportscar = new Vehiculo();
un método se llama argumento. Dentro del método, la variable que recibe el argumento se llama parámetro.
Los parámetros se declaran dentro de los paréntesis que siguen al nombre del método. La sintaxis de
int rango1, rango2;
declaración de parámetro es la misma que la utilizada para las variables.
minivan.mpg=20;
Aquí hay un ejemplo simple del uso de parámetros. Dentro de la clase ComprobarNumero, el
método esPar() devuelve true si el valor que se pasa es par. Devuelve false de lo contrario. Por lo tanto, esPar()
//Asigando valores a los campos en minivan
tiene un tipo de retorno booleano.
sportscar.pasajeros=10;
sportscar.capacidad=25;
//Un ejemplo siemple del uso de parámetros
sportscar.mpg=30;
class ComprobarNumero {
rango1=minivan.rango();
//Retorna true si x es par
rango2=sportscar.rango();
boolean esPar(int x){
if ((x%2)==0) return true;
System.out.println("La Minivan puede llevar " +minivan.pasajeros +". Con rango de: "+rang else return false;
System.out.println("El Sportscar puede llevar " +minivan.pasajeros +". Con rango de: "+ra }
sportscar.rango();
}
class ParametroDemo {
Salida:
El Sportscar puede llevar 9. Con rango de: 750 if (e.esPar(8)) System.out.println("8 es par.");
}
Salida:
En los ejemplos anteriores, las variables de instancia de cada objeto Vehiculo debían establecerse manualmente
usando una secuencia de instrucciones, como por ejemplo:
10 es par.
8 es par. minivan.pasajeros = 9;
minivan.capacidad = 15;
En el programa, esPar() se llama tres veces y cada vez se pasa un valor diferente. Miremos este proceso de minivan.mpg = 20;
cerca. Primero, observe cómo se llama esPar(). El argumento se especifica entre paréntesis.
Un enfoque como lo anterior nunca se usaría en un código Java escrito profesionalmente. Además de ser
Cuando se usa esPar() la primera vez, se pasa al valor 10. Por lo tanto, cuando esPar() comienza a propenso a errores (puede olvidarse de configurar uno de los campos), simplemente hay una mejor manera de
ejecutarse, el parámetro x recibe el valor de 10. lograr esta tarea: con un constructor.
En la segunda llamada, 9 es el argumento, y x, entonces, tiene el valor de 9.
En la tercera llamada, el argumento es 8, que es el valor que recibe x.
Table de Contenido
El punto es que el valor pasado como argumento cuando se llama a esPar() es el valor recibido por su × 1. Qué es un constructor en Java
parámetro, x.
2. Constructores parametrizados
3. Ejemplo de Constructor en Java
Un método puede tener más de un parámetro. Simplemente declare cada parámetro, separando uno del
siguiente con una coma. Por ejemplo, la clase Divisor define un método llamado esDivisor() que determina si el
primer parámetro es divisor del segundo.
1. Qué es un constructor en Java
//Un ejemplo siemple del uso de parámetros
Un constructor inicializa un objeto cuando se crea. Tiene el mismo nombre que su clase y es
class Divisor {
sintácticamente similar a un método. Sin embargo, los constructores no tienen un tipo de devolución
explícito. Normalmente, usará un constructor para dar valores iniciales a las variables de instancia definidas por
la clase, o para realizar cualquier otro procedimiento de inicio requerido para crear un objeto completamente
//Retorna true si x es par
formado.
boolean esDivisor(int a, int b){
Todas las clases tienen constructores, ya sea que usted defina uno o no, porque Java proporciona
else return false;
automáticamente un constructor predeterminado. En este caso, las variables de miembro no inicializadas
}
tienen sus valores predeterminados, que son cero, null y false, para tipos numéricos, tipos de referencia y
}
booleanos, respectivamente. Una vez que defines tu propio constructor, el constructor predeterminado ya no se
usa.
class DivisorDemo {
Aquí hay un ejemplo simple que usa un constructor:
public static void main(String[] args) {
Salida:
2 es Divisor de 20
Tenga en cuenta que cuando se llama a esDivisor(), los argumentos también están separados por comas. Al
usar múltiples parámetros, cada parámetro especifica su propio tipo, que puede diferir de los demás.
// ...
2. Constructores parametrizados
class MiClase {
En el ejemplo anterior, se utilizó un constructor sin parámetros. Aunque esto está bien para algunas situaciones,
int x;
la mayoría de las veces necesitará un constructor que acepte uno o más parámetros.
MiClase(){
Los parámetros se agregan a un constructor de la misma manera que se agregan a un método: simplemente
declararlos dentro del paréntesis después del nombre del constructor. Por ejemplo, aquí, MiClase tiene un
x=10;
constructor parametrizado:
}
}
//Un ejemplo de constructor parametrizado
class ConstructorDemo {
class MiClase {
x=i;
} }
MiClase(){
MiClase t1= new MiClase(15);
x=10;
MiClase t2= new MiClase(28);
Este constructor asigna a la variable de instancia x de MiClase el valor de 10. Este constructor es llamado por }
15 - 28
En esta versión del programa, el constructor MiClase() define un parámetro llamado i, que se usa para inicializar
la variable de instancia, x. Por lo tanto, cuando la línea:
ⓘ
MiClase t1= new MiClase();
3. Ejemplo de Constructor en Java
El constructor MiClase() es llamado en el objeto t1, dando a t1.x el valor de 10. Lo mismo es cierto para t2. Siguiendo nuestro ejemplo anterior, vamos a agregar un constructor a la clase Vehiculo:
Después de la construcción, t2.x tiene el valor de 10. Por lo tanto, el resultado del programa es:
Salida:
10 - 10
los valores 9,15,20 se pasan al constructor Vehiculo() cuando new crea el objeto. Por lo tanto, la copia
//Un ejemplo de constructor
de pasajeros, capacidad y mpg de minivan contendrá los valores 9,15,20, respectivamente. El resultado de este
programa es el mismo que la versión anterior.
class Vehiculo {
pasajeros=p;
capacidad=c;
mpg=m;
//Retornando el rango
int rango(){
return mpg*capacidad;
return (double)miles/mpg;
class DemoVehiculo {
double galones;
galones=minivan.capacidadnueva(distancia);
galones=sportscar.capacidadnueva(distancia);
Salida:
1. Clases Locales
Las clases locales internas no son miembros de ninguna clase adjunta. Pertenecen al bloque en el que están
definidos, debido a que las clases internas locales no pueden tener ningún modificador de acceso asociado. Sin
embargo, se pueden marcar como final o abstract. Estas clases tienen acceso a los campos de la clase que lo ⓘ
encierra. La clase interna local debe crearse una instancia en el bloque en el que están definidas.
Externa.class
1. El alcance de la clase interna local está restringido al bloque en el que está definidos. 2. Clase interna local dentro de un método
2. La clase interna local no se puede ser instanciado desde fuera del bloque donde se creó.
Ejemplo:
3. Hasta JDK 7, la clase interna local solo puede acceder a la variable local final del bloque envolvente . Sin
embargo, a partir de JDK 8, es posible acceder a la variable local no final del bloque delimitador en la clase
interna local.
5. Las clases internas locales pueden extender una clase abstracta o también pueden implementar una interfaz.
//Clase externa
class ClaseExterna
efectivamente final.
// por lo tanto, este código solo funcionará en JDK 8
class Interna {
Por ejemplo, si agrega la instrucción en el constructor de clase interna o en cualquier método de clase interna
private int divisor;
en el ejemplo anterior:
private int resto;
public Interna()
public Interna() {
divisor = 4;
suma = 50;
resto = suma & divisor;
divisor = 4;
resto = sum%divisor;
}
private int getDivisor(){
return divisor;
compilador de Java genera un mensaje de error similar a “las variables locales a las que se hace referencia
desde una clase interna deben ser finales o efectivamente finales“.
private int getResto(){
return suma%divisor;
}
3. Clase interna local dentro de una declaración if
System.out.println("Divisor: "+interna.getDivisor());
System.out.println("Resto: "+interna.getResto());
System.out.println("Cociente: "+interna.getCociente());
externa.getValor();
Salida:
Divisor: 4
Resto: 0
Cociente: 5
//Clase externa
//Clase externa
class ClaseExterna
public class ClaseExterna
{
{
return dato;
{
}
private int getDato()
{
if (externa.getDato()<20){
return 5;
return externa.dato;
}
} }
}
}
System.out.println(interna.getValor());
return interna.getDato();
}
}
else {
}
{
}
ClaseExterna externa = new ClaseExterna();
} System.out.println(externa.getValor(10));
Salida: }
Salida:
Dentro de la clase interna.
10
Compilation error
4. Demostrando códigos erróneos para la clase Explicación: El programa anterior causa un error de compilación porque la clase interna no se puede declarar
interna como static. Las clases internas están asociadas con el bloque en el que están definidas y no con la clase
externa (ClaseExterna en este caso).
Ejemplo:
Ejemplo:
// Programa Java para demostrar
En Java, puede definir una clase anidada. Esta es una clase que se declara dentro de otra clase.
// el alcance de la clase interna
Francamente, la clase anidada es un tema algo avanzado. De hecho, las clases anidadas ni siquiera estaban
permitidas en la primera versión de Java. No fue hasta Java 1.1 que se agregaron.
//Clase externa
Sin embargo, es importante que sepa cuáles son y la mecánica de cómo se utilizan, ya que juegan un papel
public class ClaseExterna
class Interna{
1. Clases Anidadas o Nested Classes
private void metodoInterno(){
}
¿Qué es una clase anidada? Las clases anidadas te permiten agrupar lógicamente clases que solo se utilizan
}
en un lugar, por lo tanto, esto aumenta el uso de la encapsulación y crea un código más fácil de leer y de
mantener.
}
Una clase anidada no existe independientemente de su clase adjunta. Por lo tanto, el alcance de una
public static void main(String[] args) {
Compilation error
Explicación: El programa anterior causa un error de compilación porque el alcance de las clases internas está
restringido al bloque en el que están definidas.
El único tipo que nos preocupa en este artículo es la variedad estática, es decir la clase anidada estática.
Sintaxis:
clase ClaseExterior
// Programa Java para demostrar el acceso a una clase anidada estática
...
//Clase externa
clase ClaseAnidada
class ClaseExterna
{
{
...
//Miembro estático
}
static int externo_x=10;
//Miembro de instancia
int externo_y=20;
//Miembro privado
Al igual que con los métodos y variables de clase, una clase anidada estática está asociada a su clase externa.
Y al igual que los métodos de clase estáticos, una clase anidada estática no puede hacer referencia
directamente a variables de instancia o métodos definidos en su clase adjunta: solo puede usarlos a través de //Clase anidada estática
void mostrar(){
System.out.println("externo_x: "+externo_x);
System.out.println("externo_privado: "+externo_privado);
// a un miembro no estático
ClaseExterna.ClaseAnidadaStatic
Por ejemplo, para crear un objeto para la clase anidada estática, use esta sintaxis: ClaseExterna.ClaseAnidadaStatic objetoAnidado= new ClaseExterna.ClaseAnidadaStatic();
objetoAnidado.mostrar();
}
Ejemplo:
Salida:
externo_x: 10
externo_privado: 30
1. Clases internas // Programa Java para demostrar el acceso a una clase interna
//Clase externa
Una clase interna tiene acceso a todas las variables y métodos de su clase externa y puede referirse a ellos class ClaseExterna
directamente de la misma manera que lo hacen otros miembros no estáticos de la clase externa. {
//Miembro estático
//Miembro de instancia
clase ClaseExterior
int externo_y=20;
...
//Miembro privado
clase ClaseInterna
private int externo_privado=30;
...
class ClaseInterna{
} void mostrar(){
System.out.println("externo_x: "+externo_x);
Una instancia de ClaseInterna puede existir solo dentro de una instancia de ClaseExterior y tiene acceso ×
System.out.println("externo_y: "+externo_y);
Para crear una instancia de una clase interna, primero debe crear una instancia de la clase externa. Luego, crea
el objeto interno dentro del objeto externo con esta sintaxis: //Puede acceder a mostrar un miembro privado de la clase externa
System.out.println("externo_privado: "+externo_privado);
class ClaseInternaDemo{
objetoInterno.mostrar();
Salida:
externo_x: 10
externo_y: 20
externo_privado: 30
//Clase externa
class ClaseExterna {
int nums[];
ClaseExterna(int n[]){
nums=n;
void analizar(){
ⓘ
System.out.println("Minimo: "+inOb.min());
Ejemplo:
System.out.println("Máximo: "+inOb.max());
System.out.println("Promedio: "+inOb.promedio());
class Interna{
int min(){
int m=nums;
if(nums<m) m= nums;
return m;
}
int max(){
int m=nums;
if (nums>m) m=nums;
return m;
}
int promedio(){
int a=0;
a+=nums;
return a/nums.length;
class ClaseAndidadaDemo {
int x[]={3,2,1,5,6,7,8,9};
extob.analizar();
Salida:
Minimo: 1
Máximo: 9
double valor;
Las clases anidadas estáticas no tienen acceso directo a otros miembros (variables y métodos no
estáticos) de la clase adjunta porque, como es estática, debe acceder a los miembros no estáticos de su Potencia(double base, int exp){
clase adjunta a través de un objeto. Es decir, no puede hacer referencia directamente a los miembros no b=base;
estáticos de su clase adjunta. Debido a esta restricción, las clases anidadas estáticas rara vez se e=exp;
utilizan. valor=1;
Las clases anidadas no estáticas (clases internas) tienen acceso a todos los miembros (variables y
ellos directamente de la misma manera que otros miembros no estáticos del exterior de la clase.
for ( ; exp>0; exp--) valor = valor * base;
double get_potencia(){
return valor;
class DemoPotencia {
Salida:
this.b=b;
valor=1;
Aquí, this se refiere al objeto sobre el que se llamó get_potencia(). Por lo tanto, this.valor se refiere a la copia
del valor de ese objeto. Por ejemplo, si get_potencia() se hubiera invocado en x, this en la declaración anterior if (e=0) return;
se habría estado refiriendo a x. Escribir la declaración sin usar this es solo una abreviatura. for ( ; e>0; e--) valor = valor * b;
En esta versión, los nombres de los parámetros son los mismos que los nombres de las variables de instancia,
por lo tanto, los ocultan. Sin embargo, this se usa para “descubrir” las variables de instancia.
ⓘ
//referir las variables de instancia de la clase actual
class Potencia {
int a;
double b; int b;
int e;
double valor;
// Constructor parametrizado
Test(int a, int b)
this.b=base;
this.a = a;
this.e=exp;
this.b = b;
this.valor=1;
}
if (exp==0) return;
void display()
}
//Visualización del valor de las variables a y b
System.out.println("a = " + a + " b = " + b);
double get_potencia(){
}
return this.valor;
}
public static void main(String[] args)
} {
En realidad, ningún programador de Java escribiría una clase Potencia como se acaba de mostrar porque no se object.display();
gana nada, y la forma estándar es más fácil. Sin embargo, esto tiene algunos usos importantes. Por ejemplo, la }
sintaxis de Java permite que el nombre de un parámetro o una variable local sea el mismo que el nombre }
de una variable de instancia.
Salida:
Cuando esto sucede, el nombre local oculta la variable de instancia. Puede obtener acceso a la variable de
instancia oculta haciendo referencia a ella a través de this. Por ejemplo, la siguiente es una forma
sintácticamente válida para escribir el constructor de Potencia(). a = 10 b = 20
class Test
int a;
{
int b;
int a;
int b;
//Constructor predeterminado
Test()
//Constructor predeterminado
{
Test()
a = 10;
{
b = 20;
this(10, 20);
}
}
//Método que devuelve la instancia de la clase actual
Test get()
//Constructor parametrizado
{
Test(int a, int b)
return this;
{
}
this.a = a;
this.b = b;
//Visualización del valor de las variables a y b
}
{
System.out.println("a = " + a + " b = " + b);
}
{
object.get().display();
Salida: }
Salida:
Dentro del constructor parametrizado
class Test
class Test {
int a;
void display()
int b;
{
// método que llama a show()
// Constructor predeterminado
this.show();
Test()
{
System.out.println("Dentro del método display");
a = 10;
}
b = 20;
}
void show() {
System.out.println("Dentro del método show");
}
Test t1 = new Test();
t1.display();
void get()
}
{
display(this);
Salida:
}
object.get();
a = 10 b = 20
class A
Los siguientes son algunos puntos importantes acerca de las matrices, arreglos o arrays de Java.
{
B obj;
En Java, todas las matrices se asignan dinámicamente. (Se analiza a continuación)
Como las matrices/arrays son objetos en Java, cada array tiene asociado una variable de instancia de
longitud (length) que contiene la cantidad de elementos que la matriz puede contener. (En otras
// Constructor parametrizado con el objeto de B
palabras, length contiene el tamaño de la matriz.)
// como un parámetro
Una variable array en Java se declara como otras variables con corchetes [] después del tipo de datos.
A(B obj)
Las variables en el array están ordenadas y cada una tiene un índice que comienza desde 0.
{
El array Java también se puede usar como un campo estático, una variable local o un parámetro de
this.obj = obj;
método.
El tamaño de un array debe especificarse mediante un valor int y no, long o short.
class B
Nota: En matemáticas, un array de una dimensión se llama vector. En este curso no ×
utilizaremos este término para no confundirlo con la clase Vector de Java.
{
int x = 5;
2.3. Accediendo a los elementos del Array usando el bucle for
// método para mostrar el valor de x
2.4. Arrays de objetos
void display()
3. Arrays multidimensionales
{
3.1. Pasar arrays a métodos
System.out.println("Valor de x en Class B: " + x);
3.2. Retornando arrays de métodos
}
Los arrays se usan para una variedad de propósitos porque ofrecen un medio conveniente de agrupar variables
relacionadas. Por ejemplo, puede usar una matriz para mantener un registro de la temperatura alta diaria
durante un mes, una lista de promedios de precios de acciones o una lista de tu colección de libros de
programación.
La ventaja principal de un array es que organiza los datos de tal manera que puede ser manipulado fácilmente.
Por ejemplo, si tiene un array que contiene los ingresos de un grupo seleccionado de hogares, es fácil calcular el
ingreso promedio haciendo un ciclo a través del array. Además, los arrays organizan los datos de tal manera que
se pueden ordenar fácilmente.
int intArray[];
int[] intArray;
byte byteArray[];
short shortArray[];
boolean booleanArray[];
long longArray[];
float floatArray[];
double doubleArray[];
ⓘ char charArray[];
Aunque los arrays en Java se pueden usar como matrices en otros lenguajes de programación, tienen un
atributo especial: se implementan como objetos. Este hecho es una de las razones por las que la discusión de //Tipos de datos definidos por el usuario
los arrays se pospuso hasta que se introdujeron los objetos. Al implementar arrays como objetos, se obtienen
varias ventajas importantes, una de las cuales es que los arrays no utilizados pueden ser recolectados.
// una serie de referencias a objetos de
// el usuario)
Un array unidimensional es una lista de variables relacionadas. Tales listas son comunes en la programación. Collection[] ca; // array de Collection
Por ejemplo, puede usar un array unidimensional para almacenar los números de cuenta de los usuarios activos
en una red. Otro array podría usarse para almacenar los promedios de bateo actuales para un equipo de
béisbol. Aunque la primera declaración anterior establece el hecho de que intArray es una variable de matriz, en
realidad no existe una matriz. Simplemente le dice al compilador que esta variable (intArray) contendrá una
matriz del tipo entero. Para vincular intArray con una matriz física real de enteros, debe asignar una
La forma general de declarar un arreglo unidimensional es: usando new y asignarlo a intArray. Ya veremos…
Nota:
Los elementos en la matriz asignada por se inicializarán automáticamente a cero (para tipos
numéricos), false (para booleano) o null (para tipos de referencia). // Programa Java para ilustrar la creación de un array de enteros,
Obtener un array es un proceso de dos pasos. Primero, debe declarar una variable del tipo de array // coloca algunos valores en la matriz, e imprime cada valor
deseado. En segundo lugar, debe asignar la memoria que mantendrá el array, usar y asignarla a la
variable del array. Por lo tanto, en Java, todos los arrays se asignan dinámicamente. class DemoArray
En una situación en la que ya se conoce el tamaño y los elementos del array, se pueden usar literales del array. // declara un array de enteros.
int[] arr;
La longitud de este array determina la longitud del array creado. // inicializa el primer elemento del array
arr = 20;
A cada elemento del array se accede a través de su índice. El índice comienza con 0 y termina en (tamaño total
del array) -1. Se puede acceder a todos los elementos de la matriz usando el bucle for en Java.
// y así...
arr = 30;
Salida:
Elemento en el índice 0 : 10
Elemento en el índice 1 : 20
Elemento en el índice 2 : 30
Elemento en el índice 3 : 40
Elemento en el índice 4 : 50
Nota: También puede acceder a los arrays de Java utilizando el bucle for-each ×
Student[] arr = new Student; //student es una clase definida por el usuario
El array Student contiene siete espacios de memoria, cada uno del tamaño de la clase Student, en los que se
puede almacenar la dirección de siete objetos de Student. Los objetos de Student deben crearse con
el constructor de la clase Student.
Ejemplo:
// un array de objetos
3. Arrays multidimensionales
class Student
Las matrices multidimensionales son matrices de matrices o arrays de arrays, donde cada elemento del array
{
contiene la referencia de otro array. Se crea una matriz multidimensional al agregar un conjunto de corchetes ([])
por dimensión. Ejemplos:
public int roll_no;
{
int[][][] intArray = new int; //una array 3D
this.roll_no = roll_no;
this.name = name;
Ejemplo:
}
class multiDimensional
{
{
{
int arr[][] = { {2,7,9},{3,6,1},{7,4,2} };
Student[] arr;
// imprimir array 2D
for (int i=0; i< 3 ; i++)
System.out.print(arr + " ");
// y así...
Salida:
arr = new Student(3,"tres");
2 7 9
3 6 1
7 4 2
// accediendo a los elementos del array
}
Al igual que las variables, también podemos pasar arrays a los métodos. Por ejemplo, en el programa siguiente
} se pasa un array al método sum para calcular la suma de los valores del array
Salida: Ejemplo:
Elemento en 0 : 1 uno
Elemento en 1 : 2 dos
Elemento en 2 : 3 tres
Elemento en 3 : 4 cuatro
Elemento en 4 : 5 cinco
¿Qué sucede si tratamos de acceder al elemento fuera del tamaño del array?
class Test
class Test
{
{
// Método principal
// Método principal
{
{
}
}
{
{
int sum = 0;
return new int[]{1,2,3};
Salida:
System.out.println("Suma de valores del array: " + sum);
1 2 3
}
Como de costumbre, un método también puede devolver un array. Por ejemplo, en el siguiente programa se
devuelve (return) un array desde el método m1.
Ejemplos:
class DemoArrayIrregular
class Test
{
{
public static void main(String args[])
{
int cursos[][]=new int[];
cursos = new int;
// array de Strings
cursos = new int;
cursos = new int;
System.out.println(intArray.getClass());
System.out.println(intArray.getClass().getSuperclass());
int i,j;
System.out.println(byteArray.getClass());
System.out.println(shortsArray.getClass());
for(i=0;i<5;i++)
System.out.println(strArray.getClass());
for (j=0;j<10;j++)
}
cursos=j+1;
for (j=0;j<2;j++)
Salida: cursos=j+1;
System.out.println("Entre Semana");
System.out.println("------------");
Aunque no hay ninguna ventaja en la asignación individual de los arrays de segunda dimensión en esta System.out.println();
situación, puede haber otras. Por ejemplo, cuando asigna por separado, no necesita asignar la misma
}
cantidad de elementos para cada índice. Como las matrices multidimensionales se implementan como arrays
de arrays, la longitud de cada array está bajo su control.
System.out.println("\nFin de Semana");
Por ejemplo, suponga que está escribiendo un programa que almacena el número de cursos en una universidad. System.out.println("--------------");
Suponga que existen 10 cursos al día durante la semana y dos cursos al día los sábados y domingos, puede for (i=5; i<7;i++) {
usar el array Cursos que se muestra en el siguiente programa para almacenar la información. System.out.print("Dia "+(i+1)+"°: ");
Observe que la longitud de la segunda dimensión para los primeros cinco índices es 10 y la longitud de la × System.out.println();
Salida:
Entre Semana
// Asignación de variables de referencias en array
------------
Dia 1°: 1 2 3 4 5 6 7 8 9 10
class AsignacionArray
Dia 2°: 1 2 3 4 5 6 7 8 9 10
{
Dia 3°: 1 2 3 4 5 6 7 8 9 10
public static void main(String args[])
Dia 4°: 1 2 3 4 5 6 7 8 9 10
{
Dia 5°: 1 2 3 4 5 6 7 8 9 10
int i;
Fin de Semana
int num1[] = new int;
--------------
int num2[] = new int;
Dia 6°: 1 2
num1=i;
aplicaciones, ya que funciona de manera contraria a lo que la gente espera encontrar cuando se encuentra una for (i=0; i<10 ; i++)
matriz multidimensional. Sin embargo, las matrices irregulares se pueden usar eficazmente en algunas num2=-i;
situaciones.
System.out.print("num1: ");
Por ejemplo, si necesita una matriz bidimensional muy grande que está escasamente poblada (es decir, × for (i=0; i<10 ; i++)
una en la que no se usarán todos los elementos), una matriz irregular podría ser una solución perfecta. System.out.print(num1 + " ");
System.out.println();
Al igual que con otros objetos, cuando asigna una variable de referencia de un array a otra, simplemente está System.out.println();
cambiando a qué objeto se refiere dicha variable. No está causando que se realice una copia del array, ni
hace que el contenido de un array se copie en la otra. Por ejemplo, considere este programa: num2=num1;
System.out.println();
num2=99;
System.out.println();
Salida:
num1: 0 1 2 3 4 5 6 7 8 9
num2: 0 -1 -2 -3 -4 -5 -6 -7 -8 -9
Como muestra en el resultado, después de la asignación de nums1 a nums2, ambas variables de referencia del
array se refieren al mismo objeto. // Programa Java para demostrar
Cuando clona un array dimensional único, como Object[], se realiza una “copia profunda” con el nuevo array que {
Ejemplo:
int cloneArray[][] = intArray.clone();
class Test
// se imprimirá true a medida que se crea una copia poco profunda
{
// es decir, sub-arrays son compartidos
{
System.out.println(intArray == cloneArray);
System.out.println(intArray == cloneArray);
false
true
true
System.out.print(cloneArray+" ");
}
}
1 2 3
Sin embargo, un clon de una matriz multidimensional (como Object [] []) es una “copia superficial”, lo que quiere
decir que crea solo un nuevo array con cada array de elementos como referencia a un array de elementos
original, pero los subcampos se comparten.
Ejemplo:
// Demostrando el uso de length en Arrays
for-each es otra técnica para recorrer arrays de manera sencilla, al igual que el bucle for, while, do-while;
class DemoArray
introducido en Java 5.
{
Table de Contenido
{
};
1. Qué es for-each
System.out.println("Longitud de num: " +num.length);
Con for:
//Usando length para inicializar lista
int nums[]={1,2,3,4,5};
lista=i*i;
int sum=0;
Con for-each:
for (int i=0; i < lista.length; i++)
System.out.println();
int nums[]={1,2,3,4,5};
int sum=0;
}
for (int x: nums) sum+=x;
}
La misma situación ocurre cuando se calcula un promedio, se busca un valor, se copia una matriz, etc. Debido a
que tales operaciones de “inicio hasta el final” son tan comunes, Java define una segunda forma del bucle for
que agiliza esta operación.
Salida:
La segunda forma de for implementa un ciclo de estilo “for-each”(para cada uno). Un bucle for-each recorre una
colección de objetos, como una matriz, de forma estrictamente secuencial, de principio a fin. En los últimos años,
Longitud de lista: 10
el estilo de bucle for-each ha ganado popularidad entre los diseñadores de lenguaje y programadores.
Longitud de num: 3
Originalmente, Java no ofrecía un bucle de estilo for-each. Sin embargo, con el lanzamiento de JDK 5, el bucle
for se mejoró para proporcionar esta opción.
Longitud de tabla: 3
Longitud de tabla: 3
Longitud de tabla: 2
El estilo for-each de for también se conoce como el bucle for mejorado. Ambos términos se usan en este ×
Longitud de tabla: 4
curso.
La lista es: 0 1 4 9 16 25 36 49 64 81
En el cuerpo del bucle, puede usar la variable del bucle que creó en lugar de usar un elemento indexado
del array. // Programa Java para ilustrar
Se usa comúnmente para iterar sobre un array o una clase de colecciones (por ejemplo, ArrayList) // bucle for-each
class For_Each
Sintaxis:
{
}
maxSoFar = num;
Es equivalente a: }
return maxSoFar;
{
}
tipo variable = arr;
3. Ejemplo con for-each
4. Limitaciones del ciclo for-each
Ejemplo:
El bucle for-each no es apropiado cuando quiere modificar el array:
num = num*2;
}
El bucle for-each no realiza un seguimiento del índice. Entonces no podemos obtener un índice del array
usando for-each.
if (num == target)
}
for-each itera hacia adelante sobre el array en pasos individuales.
// Uso de for-each para array de dos dimensiones
class DemoForEach
// esto no se puede convertir a un bucle for-each
System.out.println(numbers);
int sum=0;
}
int nums[][]= new int ;
nums=(i+1)*(j+1);
if (numbers == arr)
{ ...
}
System.out.println("Valor de: "+y);
sum+=y;
El for mejorado también funciona en arreglos multidimensionales. Recuerde, sin embargo, que en Java, los
arreglos multidimensionales consisten en arrays de arrays. (Por ejemplo, una matriz bidimensional es una array }
de arrays unidimensionales). }
Salida:
Leer sobre Arrays
Valor de: 2
Valor de: 2
Valor de: 4
Esto es importante cuando se itera sobre un array multidimensional porque cada iteración obtiene el siguiente Valor de: 6
array, no un elemento individual. Además, la variable de iteración en el bucle for debe ser compatible con el tipo Suma total: 18
de array que se obtiene.
En el programa, preste especial atención a esta línea:
Por ejemplo, en el caso de un array bidimensional, la variable de iteración debe ser una referencia a una array
unidimensional. En general, cuando se usa for-each para iterar sobre un arreglo de N dimensiones, los objetos
obtenidos serán arreglos de N-1 dimensiones. Para comprender las implicaciones de esto, considere el siguiente for (int x []: nums) {
programa. Utiliza bucles anidados para obtener los elementos de un arreglo bidimensional en orden de fila, del
primero al último.
Observe cómo se declara x. Es una referencia a un array unidimensional de enteros. Esto es necesario
porque cada iteración de for obtiene el siguiente array en nums, comenzando con el array especificado
por nums. El ciclo for interno recorre cada una de estos arreglos, mostrando los valores de cada elemento.
Aprenda sobre la clase String en Java desde cero. Conozca las diferentes formas de declarar String en Java y
cómo usar los métodos de la clase String.
Desde el punto de vista de la programación diaria, uno de los tipos de datos más importantes de Java
es String. String define y admite cadenas de caracteres. En algunos otros lenguajes de programación, una
cadena o string es una matriz o array de caracteres. Este no es el caso con Java. En Java, los String son
objetos.
En realidad, has estado usando la clase String desde el comienzo del curso, pero no lo sabías. Cuando crea un
literal de cadena, en realidad está creando un objeto String. Por ejemplo, en la declaración:
ⓘ
System.out.println("En Java, los String son objetos"); // Uso de String
class DemoString
El String “En Java, los String son objetos”. automáticamente se convierte en un objeto String por Java. Por lo {
tanto, el uso de la clase String ha estado “debajo de la superficie” en los programas anteriores. En las siguientes public static void main(String args[])
secciones, aprenderá a manejarlo de manera explícita. Tenga en cuenta, sin embargo, que la clase String es {
bastante grande, y solo arañaremos su superficie aquí. Es una clase que querrás explorar por sí misma. //Declaración de String de diferentes maneras
Table de Contenido
String str3=new String(str2);
1. Construyendo String
Puede construir un String igual que construye cualquier otro tipo de objeto: utilizando new y llamando al
constructor String. Por ejemplo: Se construyen de varias maneras
String substring (int i): Devuelve la subcadena del i-ésimo carácter de índice al final.
En este caso, str se inicializa en la secuencia de caracteres “Estoy aprendiendo sobre String en
JavadesdeCero.”. Una vez que haya creado un objeto String, puede usarlo en cualquier lugar que permita una
cadena entrecomillada. Por ejemplo, puede usar un objeto String como argumento para println(), como se "Javadesdecero.es".substring(4); // retorna desdecero.es
muestra en este ejemplo:
String substring (int i, int j): Devuelve la subcadena del índice i a j-1.
String s2 = "desdeCero;
String toLowerCase(): Convierte todos los caracteres de String a minúsculas.
String salida = s1.concat(s2); // retorna "JavadesdeCero"
String palabra1 = "HoLa";
int indexOf (String s): Devuelve el índice dentro de la cadena de la primera aparición de la cadena String palabra2 = palabra1.toLowerCase(); // retorna "hola"
especificada.
String toUpperCase(): Convierte todos los caracteres de String a mayúsculas.
String s = "Java desde Cero";
int salida = s.indexOf('a',3); //retorna 3 String palabra1 = " Java desde Cero ";
boolean equalsIgnoreCase (String otroString): Compares string to another string, ignoring case
considerations.
3. Ejemplo de todos los métodos de String
Boolean salida= "Java".equalsIgnoreCase("Java"); // retorna true
int compareToIgnoreCase (String otroString): Compara dos cadenas lexicográficamente, ignorando las
consideraciones case.
// de la clase String.
palabra1.toLowerCase());
class DemoMetodosString
// Conversión de cases
palabra1.toUpperCase());
String s= "JavadesdeCero";
// Recortando la palabra
// Reemplazar caracteres
+ s.charAt(3));
// al final de la cadena
Salida:
System.out.println("Substring = " + s.substring(2,5));
String s1 = "Java";
Character at 3rd position = a
String s2 = "desdeCero";
Substring adesdeCero
s1.concat(s2));
String concatenado = JavadesdeCero
Índice de Cero: 11
s4.indexOf("Cero"));
Si s1 = s2: false
System.out.println("Índice de a = " +
Reemplazando Y por J -> JavadesdeCero
s4.indexOf('a',3));
Al igual que cualquier otro tipo de datos, los String se pueden ensamblar en arrays. Por ejemplo:
out = "Java".equals("Java");
// Conversión de cases
class StringArray
{
class SubString
{
public static void main (String[] args)
String str="Java desde Cero";
System.out.print(s+ "");
System.out.println("\n");
String substr=str.substring(5,15);
//Cambiando un String
System.out.println("str: "+str);
str="Curso";
System.out.println("substr: "+substr);
str="Online";
}
}
System.out.println("Array Modificado: ");
System.out.println("\n");
}
str: Java desde Cero
Se muestra el resultado de este programa: Como puede ver, la cadena original str no se modifica, y substr contiene la subcadena.
Array Original:
6. String en Argumentos de Línea de Comandos
JavadesdeCero
Ahora que conoce la clase String, puede comprender el parámetro args en main() que ha estado en cada
Array Modificado:
programa mostrado hasta ahora. Muchos programas aceptan lo que se llaman argumentos de línea de
JavaCursoOnline comandos. Un argumento de línea de comandos es la información que sigue directamente el nombre del
programa en la línea de comando cuando se ejecuta.
5. Los String son inmutables Para acceder a los argumentos de la línea de comandos dentro de un programa Java es bastante fácil: se
almacenan como cadenas en la matriz String pasada a main (). Por ejemplo, el siguiente programa muestra
todos los argumentos de línea de comandos con los que se llama:
El contenido de un objeto String es inmutable. Es decir, una vez creada, la secuencia de caracteres que
compone la cadena no se puede modificar. Esta restricción permite a Java implementar cadenas de manera
más eficiente. Aunque esto probablemente suene como un serio inconveniente, no lo es. // Mostrando Información de Línea de Comando
Cuando necesite una cadena que sea una variación de una que ya existe, simplemente cree una nueva cadena class DemoLC
que contenga los cambios deseados. Como los objetos String no utilizados se recolectan de forma automática, {
ni siquiera tiene que preocuparse por lo que sucede con las cadenas descartadas. Sin embargo, debe quedar
public static void main (String[] args)
claro que las variables de referencia de cadena pueden, por supuesto, cambiar el objeto al que hacen referencia.
Es solo que el contenido de un objeto String específico no se puede cambiar después de haber sido creado. {
métodos de String: substring(). El método substring() devuelve una nueva cadena que contiene una parte System.out.println("Estos son: ");
especificada de la cadena invocadora. Como se fabrica un nuevo objeto String que contiene la subcadena, la for (int i=0; i<args.length; i++)
cadena original no se altera y la regla de inmutabilidad permanece intacta. La forma de substring( ) que vamos a System.out.println("arg["+i+"]: "+args);
String numeros[][]={
Estos son:
{ "Juan", "145-478"},
arg: uno
{ "Javier", "789-457"},
arg: dos
{ "Maria", "784-554"}
arg: tres
};
int i;
if (args.length != 1)
else {
break;
if (i == numeros.length)
System.out.println("Nombre no encontrado.");
Observe que el primer argumento se almacena en el índice 0, el segundo argumento se almacena en el índice 1,
y así sucesivamente. Alex: 123-456
Para tener una idea de la forma en que se pueden usar los argumentos de la línea de comandos, considere el
siguiente programa. Se necesita un argumento de línea de comandos que especifique el nombre de una
persona. Luego busca a través de una matriz bidimensional de cadenas para ese nombre. Si encuentra una
coincidencia, muestra el número de teléfono de esa persona.
Table de Contenido
Modificadores de acceso en Java 1. Todos los Modificadores de Acceso
Intermedio POO 2. Modificador de acceso por defecto (default)
3. Modificador de acceso privado (private)
2 Comentarios por Alex Walton 4. Modificador de acceso protegido (protected)
5. Modificador de acceso público (public)
6. Modificadores que no son de acceso
7. Puntos importantes
Aunque el enfoque de Java es un poco más sofisticado, en esencia, hay dos tipos básicos de miembros de la clase: 2. Private
público (public) y privado (private). Se puede acceder libremente a un miembro público mediante un código definido
fuera de su clase. Se puede acceder a un miembro privado solo por otros métodos definidos por su clase. Es a 3. Protected
través del uso de miembros privados que el acceso está controlado.
4. Public
Restringir el acceso a los miembros de una clase es una parte fundamental de la programación orientada a objetos,
ya que ayuda a evitar el mal uso de un objeto.
Tabla de Modificadores de Acceso en Java
Al permitir el acceso a datos privados solo a través de un conjunto de métodos bien definidos, puede evitar que se Modificador/Acceso Clase Paquete Subclase Todos
asignen valores incorrectos a esos datos, por ejemplo, realizando una verificación de rango.
public Sí Sí Sí Sí
No es posible que el código fuera de la clase establezca el valor de un miembro privado directamente.
También puede controlar con precisión cómo y cuándo se utilizan los datos dentro de un objeto. protected Sí Sí Sí No
Por lo tanto, cuando se implementa correctamente, una clase crea una “caja negra” que se puede usar, pero × default Sí Sí No No
cuyo funcionamiento interno no está abierto a alteraciones.
private Sí No No No
Hasta este punto, no ha tenido que preocuparse por el control de acceso porque Java proporciona una
configuración de acceso predeterminada en la que, para los tipos de programas mostrados anteriormente, los
miembros de una clase están disponibles libremente para el código en otro programa. (Por lo tanto, para los
ejemplos anteriores, la configuración de acceso default es esencialmente public.)
2. Modificador de acceso por defecto (default)
Cuando no se especifica ningún modificador de acceso para una clase, método o miembro de datos, se dice estar
teniendo modificador de acceso default por defecto.
Los miembros de datos, clase o métodos que no se declaran utilizando ningún modificador de acceso, es decir, que
tengan un modificador de acceso predeterminado, solo son accesibles dentro del mismo paquete.
En este ejemplo, crearemos dos paquetes y las clases en los paquetes tendrán los modificadores de acceso
predeterminados e intentaremos acceder a una clase de un paquete desde otra clase del segundo paquete.
ⓘ
Aunque es conveniente para clases simples (y programas de ejemplo en cursos como este), esta configuración
predeterminada es inadecuada para muchas situaciones del mundo real. Aquí presentamos otras funciones
de control de acceso de Java.
package p1;
// al usar la clase desde un mismo paquete
// con modificador private
class DemoDefault {
void mostrar()
class A {
{
private void mostrar() {
System.out.println("Hola Mundo!");
System.out.println("Java desde Cero");
}
}
}
}
class B{
// modificador default
obj.mostrar();
package p2;
}
import p1.*;
}
// Esta clase tiene un modificador de acceso predeterminado
Salida:
public static void main(String args[])
obj.mostrar();
}
4. Modificador de acceso protegido (protected)
}
// el modificador protected
El modificador de acceso privado se especifica con la palabra clave . Los métodos o los miembros de datos package p1;
declarados como privados solo son accesibles dentro de la clase en la que se declaran.
public class A {
Cualquier otra clase del mismo paquete no podrá acceder a estos miembros.
Las clases e interfaces no se pueden declarar como privadas (private). protected void mostrar(){
En este ejemplo, crearemos dos clases A y B dentro del mismo paquete p1. Declararemos un método en la clase A System.out.println("Java desde Cero");
como privado e intentaremos acceder a este método desde la clase B y veremos el resultado. }
}
// Programa Java para ilustrar
Java desde Cero
// el modificador protected
package p2;
6. Modificadores que no son de acceso
// importar todas las clases en el paquete p1
import p1.*;
En Java, tenemos 7 modificadores que no son de acceso o, a veces, también llamados especificadores. Se usan
con clases, métodos, variables, constructores, etc. para proporcionar información sobre su comportamiento a
public class B extends A {
la JVM. Y son:
public static void main(String[] args) {
El modificador de acceso público tiene el alcance más amplio entre todos los demás modificadores de
acceso.
Las clases, métodos o miembros de datos que se declaran como públicos son accesibles desde cualquier
lugar del programa. No hay restricciones en el alcance de los miembros de datos públicos.
// el modificador public
package p1;
public class A {
// el modificador protected
package p2;
import p1.*;
obj.mostrar();
Salida:
class Demo {
a = i;
b = j;
Cuando pasamos un tipo primitivo a un método, se pasa por valor. Pero cuando pasamos un objeto a un método, la }
situación cambia drásticamente, porque los objetos se pasan por lo que efectivamente es llamado, por referencia.
public class Test {
Java hace esta cosa interesante que es una especie de híbrido entre pasar por valor y pasar por referencia.
Básicamente, la función no puede cambiar un parámetro, pero la función puede pedirle al parámetro que se cambie public static void main(String args[]) {
a sí mismo llamando a algún método dentro de él. Demo ob1 = new Demo(100, 22);
Al crear una variable de un tipo de clase, solo creamos una referencia a un objeto. Por lo tanto, cuando Demo ob3 = new Demo(-1, -1);
pasemos esta referencia a un método, el parámetro que lo recibe se referirá al mismo objeto que el referido
Esto significa efectivamente que los objetos actúan como si se pasaran a los métodos mediante el uso de System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));
Los cambios en el objeto dentro del método se reflejan en el objeto utilizado como argumento.
}
En Java podemos pasar objetos a métodos. Por ejemplo, considere el siguiente programa: Demo ob1 = new Demo(100, 22);
Desde el lado del método, se declara una referencia de tipo Demo con un nombre obj y se asigna
inicialmente nulo.
2. Definir un constructor que toma un objeto de su
clase como un parámetro
Uno de los usos más comunes de los parámetros de objeto implica constructores. Con frecuencia, en la práctica,
hay necesidad de construir un nuevo objeto para que inicialmente sea el mismo que un objeto existente. Para hacer
esto, o podemos usar el método Object.clone() o definir un constructor que tome un objeto de su clase como un
parámetro. La segunda opción se ilustra en el siguiente ejemplo:
Como llamamos al método equalTo, la referencia ‘obj’ se asignará al objeto que se pasa como un argumento,
es decir, ‘obj’ se referirá a ‘ob2’ cuando la siguiente sentencia se ejecute.
Ahora, como podemos ver, se llama al método equalTo sobre ‘ob1’, y ‘obj’ se refiere a ‘ob2’. Dado que los
valores de ‘a’ y ‘b’ son los mismos para ambas referencias, entonces si (condición) es verdadero, entonces
boolean retornará true.
Ahora, como podemos ver, el método equalTo se llama en ‘ob1’, y ‘obj’ se refiere a ‘ob3’. Como los valores
de ‘a’ y ‘b’ no son los mismos para ambas referencias, entonces si (condición) es falso, entonces el bloque
se ejecutará y se devolverá false.
class Caja {
Caja(Caja ob)
Volumen de mi miclon es 3000.0
{
ancho = ob.ancho;
alto = ob.alto;
largo = ob.largo;
3. Devolución de objetos
}
En Java, un método puede devolver cualquier tipo de datos, incluidos los objetos. Por ejemplo, en el siguiente
//constructor utilizado cuando todas
programa, el método incrByTen() devuelve un objeto en el que el valor de a (una variable entera) es diez mayor que
//las dimensiones están especificadas
en el objeto invocado.
ancho = w;
class DemoRetornarObjeto {
alto = h; int a;
largo = d;
}
DemoRetornarObjeto(int i)
double volumen()
a = i;
{
}
}
// Este método devuelve un objeto
}
DemoRetornarObjeto incrByTen(){
DemoRetornarObjeto ob1 = new DemoRetornarObjeto(2);
double vol;
DemoRetornarObjeto ob2;
vol = miCaja.volumen();
System.out.println("ob2.a: " + ob2.a);
vol = miclon.volumen();
}
System.out.println("Volumen de mi miclon es " + vol);
}
Salida:
}
Salida: ob1.a: 2
ob2.a: 12
Nota: Cuando se pasa una referencia de objeto a un método, la referencia misma se pasa mediante el uso de
llamada por valor. Sin embargo, dado que el valor que se pasa se refiere a un objeto, la copia de ese valor seguirá
haciendo referencia al mismo objeto que hace su argumento correspondiente.
Hasta este punto, los ejemplos han estado usando tipos simples como parámetros para los métodos. Sin embargo,
Este artículo analiza el manejo de excepciones. Una excepción es un error que ocurre en tiempo de ejecución.
es correcto y común pasar objetos a los métodos.
Utilizando el subsistema de manejo de excepciones de Java, puede, de una manera estructurada y controlada,
manejar los errores de tiempo de ejecución.
Aunque la mayoría de los lenguajes de programación modernos ofrecen algún tipo de manejo de excepciones, el
soporte de Java es fácil de usar y flexible.
Table de Contenido
1. Manejo de Excepciones
2. Jerarquía de excepciones
3. Fundamentos de manejo de excepciones
3. Uso de try y catch
3.1. Un ejemplo de excepción simple
3.2. Un ejemplo de excepción con método
3.3. Captura de excepciones de subclase
4. Los bloques try pueden ser anidados
5. Lanzar una excepción
6. Re-lanzar una excepción:
7. Una mirada más cercana a Throwable
8. Uso de finally
9. Uso de throws
9.1. Ejemplo con throws
10. Tres características adicionales de excepción
9.1. Característica multi-catch
1. Manejo de Excepciones
Una ventaja principal del manejo de excepciones es que automatiza gran parte del código de manejo de errores
que previamente debía ingresarse “a mano” en cualquier programa grande. Por ejemplo, en algunos lenguajes de
computadora más antiguos, los códigos de error se devuelven cuando falla un método, y estos valores se deben
verificar manualmente, cada vez que se llama al método. Este enfoque es tedioso y propenso a errores.
El manejo de excepciones agiliza el manejo de errores al permitir que tu programa defina un bloque de código,
llamado manejador de excepción, que se ejecuta automáticamente cuando ocurre un error. No es necesario
verificar manualmente el éxito o el fracaso de cada operación específica o llamada a un método. Si se produce un
error, será procesado por el manejador de excepciones.
Otra razón por la que el manejo de excepciones es importante es que Java define excepciones estándar para
errores comunes del programa, como por ejemplo, dividir por cero o no encontrar el archivo. Para responder a
estos errores, tu programa debe vigilar y manejar estas excepciones. Además, la biblioteca API de Java hace un
uso extensivo de excepciones.
En el análisis final, ser un programador de Java exitoso significa que usted es completamente capaz de navegar
por el subsistema de manejo de excepciones de Java. ¡Empezamos!
2. Jerarquía de excepciones
En Java, todas las excepciones están representadas por clases. Todas las clases de excepción se derivan de una
clase llamada Throwable. Por lo tanto, cuando se produce una excepción en un programa, se genera un objeto de
algún tipo de clase de excepción.
se ejecuta. Es decir, si el tipo de excepción especificado por una instrucción catch coincide con el de la excepción,
entonces se ejecuta esa instrucción de catch (y todos los demás se anulan). Cuando se detecta una
excepción, exOb recibirá su valor.
2. Los errores que resultan de la actividad del programa están representados por subclases de Exception. Por
public static void main(String[] args) {
ejemplo, dividir por cero, límite de matriz y errores de archivo caen en esta categoría. En general, tu programa
debe manejar excepciones de estos tipos. Una subclase importante de Exception es RuntimeException, que se int nums[]=new int;
try {
nums=10;
y finally. Forman un subsistema interrelacionado en el que el uso de uno implica el uso de otro. A lo largo
curso, cada palabra clave se examina en detalle. Sin embargo, es útil desde el principio tener una comprensión System.out.println("Índice fuera de los límites!");
general del papel que cada uno desempeña en el manejo de excepciones. En resumen, así es como funcionan. }
Las declaraciones de programa que desea supervisar para excepciones están contenidas dentro de un bloque try. }
Si se produce una excepción dentro del bloque try, se lanza. Tu código puede atrapar esta excepción }
usando catch y manejarlo de una manera racional. Las excepciones generadas por el sistema son lanzadas
automáticamente por el sistema de tiempo de ejecución de Java. Para lanzar manualmente una excepción, use la
Salida:
palabra clave throw. En algunos casos, una excepción arrojada por un método debe ser especificada como tal por
una cláusula throws. Cualquier código que debe ejecutarse al salir de un bloque try se coloca en un
bloque finally. Antes de que se genere la excepción.
Aunque es bastante breve, el programa anterior ilustra varios puntos clave sobre el manejo de excepciones:
En el centro del manejo de excepciones están y . Estas palabras clave trabajan juntas; no puedes atrapar (catch)
sin intentarlo (try). Aquí está la forma general de los bloques de manejo de excepciones try/catch: Primero, el código que desea monitorear para detectar errores está dentro de un bloque try.
En segundo lugar, cuando se produce una excepción (en este caso, debido al intento de indexar nums más
allá de sus límites), la excepción se emite desde el bloque try y es atrapada por la instrucción catch. En este
try{
punto, el control pasa al catch, y el bloque try finaliza.
//bloque de código para monitorear errores
Es decir, no se llama a catch. Por el contrario, la ejecución del programa se transfiere a él. Por lo tanto, la
}
instrucción que sigue a nunca se ejecutará.
catch (TipoExcepcion1 exOb){
Después de que se ejecuta la instrucción catch, el control del programa continúa con las declaraciones que
//Manejador para TipoExepción1
siguen el catch. Por lo tanto, es el trabajo de tu controlador de excepción remediar el problema que causó la
excepción para que la ejecución del programa pueda continuar normalmente.
}
Aquí, TipoExcepcion es el tipo de excepción que ha ocurrido. Cuando se lanza una excepción, es atrapada por su nums = 10;
instrucción catch correspondiente, que luego procesa la excepción. Como muestra la forma general, puede haber
más de una declaración catch asociada con un try. El tipo de la excepción determina qué declaración de captura
por
Hay un punto importante sobre declaraciones de múltiples catch que se relaciona con subclases. Una
nums = 10; cláusula catch para una superclase también coincidirá con cualquiera de sus subclases.
Ahora, no se genera ninguna excepción, y el bloque catch no se ejecuta. Por ejemplo, dado que la superclase de todas las excepciones es Throwable, para atrapar todas las excepciones
posibles, capture Throwable. Si desea capturar excepciones de un tipo de superclase y un tipo de subclase,
coloque la subclase primero en la secuencia de catch. Si no lo hace, la captura de la superclase también atrapará
3.2. Un ejemplo de excepción con método todas las clases derivadas. Esta regla se autoejecuta porque poner primero la superclase hace que se cree un
código inalcanzable, ya que la cláusula catch de la subclase nunca se puede ejecutar. En Java, el código
Es importante comprender que todo código dentro de un bloque try se supervisa para detectar excepciones. Esto inalcanzable es un error.
incluye excepciones que pueden ser generadas por un método llamado desde dentro del bloque try.
Por ejemplo, considere el siguiente programa:
Una excepción lanzada por un método llamado desde dentro de un bloque try puede ser atrapada por las
declaraciones catch asociadas con ese bloque try, asumiendo, por supuesto, que el método no captó la excepción
en sí misma. Por ejemplo, este es un programa válido: // Las subclases deben preceder a las superclases
for (int i=0;i< nums.length;i++){
nums=10;
}catch (ArrayIndexOutOfBoundsException exc){
System.out.println("Esto no se mostrará.");
//Capturando la excepción (subclase)
}
System.out.println("No se encontró ningún elemento.");
} }
try {
}
ExcEjemplo.genExcepcion();
//Capturando la excepción
Salida:
System.out.println("Índice fuera de los límites!");
}
4 / 2 es 2
}
16 / 4 es 4
} 32 / 4 es 8
Salida: 128 / 8 es 16
int denom[]={2,0,4,4,0,8};
try{
//Capturando la excepción
//Capturando la excepción
System.out.println("Excepción capturada.");
}
System.out.println("Después del bloque try/catch");
//Capturando la excepción
Salida:
System.out.println("ERROR: Programa terminado.");
}
Excepción capturada.
16 / 4 es 4
manejadores/controladores a la excepción.
ERROR: Programa terminado.
Por ejemplo, quizás un manejador de excepciones maneja un aspecto de una excepción, y un segundo manejador
se enfrenta a otro aspecto. Recuerde, cuando vuelve a lanzar una excepción, no se volverá a capturar por la
En este ejemplo, una excepción que puede ser manejada por el try interno, en este caso, un error de división por misma declaración catch. Se propagará a la siguiente declaración de catch. El siguiente programa ilustra
cero, permite que el programa continúe. Sin embargo, un error de límite de matriz es capturado por la try externo, el relanzamiento de una excepción:
lo que hace que el programa finalice.
Aunque ciertamente no es la única razón para las instrucciones try anidadas, el programa anterior hace un punto
importante que se puede generalizar. A menudo, los bloques try anidados se usan para permitir que las
diferentes categorías de errores se manejen de diferentes maneras. Algunos tipos de errores son catastróficos
y no se pueden solucionar. Algunos son menores y pueden manejarse de inmediato.
Puede utilizar un bloque try externo para detectar los errores más graves, permitiendo que los ×
bloques try internos manejen los menos serios.
//Capturando la excepción
void
}
} void
printStackTrace printStackTrace(PrintWriter Envía la traza de errores a la secuencia especificada.
s)
public class RethrowDemo {
4 / 2 es 2
16 / 4 es 4
32 / 4 es 8
128 / 8 es 16
En este programa, los errores de división por cero se manejan localmente, mediante genExcepcion(), pero se
vuelve a generar un error de límite de matriz. En este caso, es capturado por main().
catch(TipoExcepcion1 exOb){
nums=10;
catch(TipoExcepcion2 exOb){
System.out.println("Esto no se mostrará.");
//manejador para TipoExcepcion2
}
}
}
//...
finally{
class MetodosThrowable{
//código final
ExcDemo.genExcepcion();
El bloque finally se ejecutará siempre que la ejecución abandone un bloque try/catch, sin importar las condiciones
}
que lo causen. Es decir, si el bloque try finaliza normalmente, o debido a una excepción, el último código ejecutado
catch (ArrayIndexOutOfBoundsException exc){
es el definido por finally. El bloque finally también se ejecuta si algún código dentro del bloque try o cualquiera de
System.out.println("Mensaje estándar: ");
sus declaraciones catch devuelve del método.
System.out.println(exc);
}
//Uso de finally
}
public static void genExcepecion(int rec) {
}
int t;
Salida:
System.out.println("Recibiendo "+rec);
try {
switch (rec){
Mensaje estándar:
case 0:
java.lang.ArrayIndexOutOfBoundsException: 7
t=10 /rec;
break;
Traza de errores:
case 1:
java.lang.ArrayIndexOutOfBoundsException: 7
at ExcDemo.genExcepcion(ExcDemo.java:8)
break;
at MetodosThrowable.main(ExcDemo.java:16)
case 2:
8. Uso de finally }
//Capturando la excepción
Algunas veces querrá definir un bloque de código que se ejecutará cuando quede un bloque try/catch. Por ejemplo, System.out.println("No se puede dividir por cero!");
una excepción puede causar un error que finaliza el método actual, causando su devolución prematura. Sin return; //retorna desde catch
embargo, ese método puede haber abierto un archivo o una conexión de red que debe cerrarse. }
Tales tipos de circunstancias son comunes en la programación, y Java proporciona una forma conveniente de //Capturando la excepción
manejarlos: finally. Para especificar un bloque de código a ejecutar cuando se sale de un bloque try/catch, incluya
System.out.println("Elemento no encontrado");
un bloque al final de una secuencia try/catch. Aquí se muestra la forma general de un try/catch que incluye finally.
}
finally {
//esto se ejecuta al salir de los blorecs try/catch
System.out.println("Saliendo de try.");
}
Salida:
//Uso de throws
class ThrowsDemo {
class FinallyDemo{
public static char prompt(String args)
UsoFinally.genExcepecion(i);
return (char) System.in.read();
System.out.println();
}
}
public static void main (String[]args){
} char ch;
try {
Como muestra la salida, no importa cómo se salga el bloque try, el bloque finally sí se ejecuta . //dado que prompt() podría arrojar una excepción,
ch = 'X';
En algunos casos, si un método genera una excepción que no maneja, debe declarar esa excepción en una
}
cláusula . Aquí está la forma general de un método que incluye una cláusula throws:
System.out.println("Usted presionó: " + ch);
} En un punto relacionado, observe que IOException está totalmente calificado por su nombre de paquete java.io.
Como aprenderá más adelante, el sistema de E/S de Java está contenido en el paquete java.io. Por lo
Aquí, lista-excepc es una lista de excepciones separadas por comas que el método podría arrojar fuera de sí tanto, IOException también está contenido allí. También habría sido posible importar java.io y luego referirme a
mismo. IOException directamente.
Quizás se pregunte por qué no necesitó especificar una cláusula throws para algunos de los ejemplos anteriores,
que arrojó excepciones fuera de los métodos. La respuesta es que las excepciones que son subclases 10. Tres características adicionales de excepción
de Error o RuntimeException no necesitan ser especificadas en una lista de throws. Java simplemente asume
que un método puede arrojar uno. Todos los otros tipos de excepciones deben ser declarados. De lo contrario, se
produce un error en tiempo de compilación. A partir de JDK 7, el mecanismo de manejo de excepciones de Java se ha ampliado con la adición de tres
características.
En realidad, usted vio un ejemplo de una cláusula throws anteriormente. Como recordará, al realizar la entrada del
teclado, necesitaba agregar la cláusula a main(). Ahora puedes entender por qué. Una declaración de entrada 1. El primero es compatible con la gestión automática de recursos, que automatiza el proceso de liberación de
podría generar una IOException, y en ese momento, no pudimos manejar esa excepción. Por lo tanto, tal un recurso, como un archivo, cuando ya no es necesario. Se basa en una forma expandida de , llamada
excepción se descartaría de main() y necesitaría especificarse como tal. Ahora que conoce excepciones, puede declaración (try con recursos), y se describe más en Java Avanzado, cuando se discuten los archivos.
manejar fácilmente IOException.
2. La segunda característica nueva se llama multi-catch.
9.1. Ejemplo con throws 3. Y la tercera a veces se llama final rethrow o more precise rethrow. Estas dos características se describen
aquí.
Veamos un ejemplo que maneja IOException. Crea un método llamado prompt(), que muestra un mensaje de
aviso y luego lee un carácter del teclado. Como la entrada se está realizando, puede ocurrir una IOException. 9.1. Característica multi-catch
Sin embargo, el método prompt() no maneja IOException. En cambio, usa una cláusula throws, lo que significa que
el método de llamada debe manejarlo. En este ejemplo, el método de llamada es main() y trata el error. El multi-catch permite capturar dos o más excepciones mediante la misma cláusula catch. Como aprendió
anteriormente, es posible (de hecho, común) que un intento sea seguido por dos o más cláusulas catch. Aunque
cada cláusula catch a menudo proporciona su propia secuencia de código única, no es raro tener situaciones en
las que dos o más cláusulas catch ejecutan la misma secuencia de código aunque atrapen diferentes excepciones.
En lugar de tener que capturar cada tipo de excepción individualmente, puede usar una única cláusula
de catch para manejar las excepciones sin duplicación de código.
Para crear un multi-catch, especifique una lista de excepciones dentro de una sola cláusula catch. Para ello,
separe cada tipo de excepción en la lista con el operador OR. Cada parámetro multi-catch es implícitamente final.
(Puede especificar explícitamente final, si lo desea, pero no es necesario.) Debido a que cada parámetro multi-
catch es implícitamente final, no se le puede asignar un nuevo valor.
catch(ArithmeticException | ArrayIndexOutOfBoundsException e) { La palabra clave super en Java es una variable de referencia que se usa para referir objetos de clase padre
(puede revisar sobre Herencia, en este enlace). Se usa principalmente en los siguientes contextos:
Aquí hay un programa simple que demuestra el uso de multi-catch:
Table de Contenido
// Uso de multi-catch
1. Uso de super con variables
// Este código requiere JDK7 o superior
char chars[]={'A','B','C'};
1. Uso de super con variables
for (int i=0; i<2;i++){
try {
if (i==0)
Este escenario ocurre cuando una clase derivada y una clase base tienen los mismos miembros de datos. En
ese caso, existe una posibilidad de ambigüedad para la JVM. Podemos entenderlo más claramente usando este
resultado=a/b; //genera un ArithmeticException
fragmento de código:
else
Ejemplo:
}catch (ArithmeticException | ArrayIndexOutOfBoundsException e){
}
/* clase base vehicle */
}
class Vehicle
}
int maxSpeed = 120;
} }
Salida:
/* subclase Car extendiendo de vehicle */
void display()
La función más precisa de rethrow restringe el tipo de excepciones que pueden volver a lanzarse solo a aquellas }
excepciones marcadas que arroja el bloque try asociado, que no son manejadas por una cláusula catch anterior, y }
que son un subtipo o supertipo del parámetro. Si bien esta capacidad puede no ser necesaria a menudo, ahora
está disponible para su uso.
/* Programa de controlador Test */
Para que la característica rethrow esté en vigor, el parámetro catch debe ser efectivamente final. Esto significa class Test
que no se le debe asignar un nuevo valor dentro del bloque catch. También se puede especificar explícitamente {
small.display();
Salida:
Salida:
Velocidad máxima: 120
En el ejemplo anterior, tanto la clase base como la subclase tienen un miembro maxSpeed. Podríamos acceder
a maxSpeed de la clase base en la sublcase usando la palabra clave super.
Ejemplo:
ⓘ
/* Clase Base Person */
class Person
Esta es una clase estudiante
{
Esta es una clase persona
void message()
{
En el ejemplo anterior, hemos visto que si solo llamamos al método message(), entonces se invoca
System.out.println("Esta es una clase persona");
el message() de la clase actual, pero con el uso de la palabra clave super, también se puede invocar
}
a message() de la superclase.
}
La palabra clave super también se puede usar para acceder al constructor de la clase padre. Una cosa más
{
importante es que ”super” puede llamar constructores tanto con parámetros como sin parámetros dependiendo
void message()
de la situación. A continuación se muestra el fragmento de código para explicar el concepto anterior:
{
class Person
void display()
{
{
Person()
message();
{
super.message();
}
}
class Test
Student()
{
super();
System.out.println("Constructor de la clase Student");
s.display();
}
class Test
Overriding en Java (Anulación de métodos)
{
POO
public static void main(String[] args)
Salida:
ⓘ
Constructor de la clase Student
En una jerarquía de clases, cuando un método en una subclase tiene el mismo tipo de retorno y firma que un
En el ejemplo anterior hemos llamado al constructor de la superclase usando la palabra clave ‘super‘ a través
método en su superclase, se dice que el método en la subclase anula (Overriding) el método en la superclase.
del constructor de la subclase.
En otras palabras, es el tipo de objeto al que se hace referencia (no el tipo de la variable de
referencia) el que determina qué versión de un método anulado se ejecutará.
ⓘ
2. Ejemplo de anulación de Método k: 3
class A {
Por ejemplo, en esta versión de B, se invoca la versión de superclase de mostrar() dentro de la versión de la
int i,j;
subclase. Esto permite que se muestren todas las variables de instancia.
i=a;
int k;
j=b;
}
B(int a, int b, int c){
super(a,b);
//Mostrar i, j
k=c;
void mostrar(){
}
}
//mostrar k - esto oculta el método mostrar() en A
} void mostrar(){
super.mostrar();
System.out.println("k: "+k);
class B extends A {
int k;
class Override{
super(a,b);
k=c;
B b=new B(1,2,3);
void mostrar(){
}
System.out.println("k: "+k);
}
Salida:
class Override{
i, j: 1, 2
Aquí, super.mostrar() llama a la versión superclase de mostrar(). La anulación del método ocurre solo cuando las
b.mostrar(); //Esto llama a mostrar() en B
firmas de los dos métodos son idénticas. Si no lo son, entonces los dos métodos están simplemente
}
sobrecargados. Por ejemplo, considere esta versión modificada del ejemplo anterior:
}
Salida:
Comencemos por replantear un principio importante: una variable de referencia de superclase puede referirse a un
class A {
objeto de subclase. Java usa este hecho para resolver llamadas a métodos anulados en tiempo de ejecución.
int i,j;
Cuando se llama a un método reemplazado a través de una referencia de superclase, Java determina qué versión
A(int a,int b){
de ese método ejecutar en función del tipo de objeto al que se hace referencia en el momento en que se produce la
i=a;
llamada. Por lo tanto, esta determinación se realiza en tiempo de ejecución. Cuando se hace referencia a diferentes
j=b;
tipos de objetos, se invocarán diferentes versiones de un método reemplazado.
}
En otras palabras, es el tipo de objeto al que se hace referencia (no el tipo de la variable de referencia) el que
//Mostrar i, j
determina qué versión de un método reemplazado se ejecutará. Por lo tanto, si una superclase contiene un método
anulado por una subclase, cuando se hace referencia a diferentes tipos de objetos a través de una variable de
void mostrar(){
} //Demostración de Polimorfismo
class Sup{
void desde(){
class B extends A {
System.out.println("desde() Sup");
int k;
super(a,b);
class Sub1 extends Sup{
k=c;
void desde(){
}
System.out.println("desde() Sub1");
//sobrecarga de mostrar()
System.out.println(msg+k);
}
void desde(){
}
System.out.println("desde() Sub2");
class Override{
}
B b=new B(1,2,3);
class Polimorfismo {
}
Sub1 subob1=new Sub1();
Esto es k: 3
referencia=superob;
i, j: 1, 2 referencia.desde();
referencia=subob1;
La versión mostrar() en B toma un parámetro de cadena (String). Esto hace que su firma sea diferente de la de A,
que no toma parámetros. Por lo tanto, no se produce anulación/overriding (ocultación de nombre). referencia.desde();
referencia=subob2;
}
Si bien los ejemplos de la sección anterior demuestran la mecánica de la anulación de método (method
más
overriding), no muestran todo su poder. La anulación de métodos forma la base de uno de los conceptos
potentes de Java: el despacho dinámico de métodos (también conocido como polimorfismo). Salida:
El envío de métodos dinámicos es el mecanismo por el cual una llamada a un método reemplazado se resuelve en
tiempo de ejecución en lugar de tiempo de compilación. El envío de métodos dinámicos es importante porque así
es como implementa Java el polimorfismo en tiempo de ejecución.
desde() Sup
desde() Sub1
Palabra Clave “final” en Java
desde() Sub2
Palabra Clave
Este programa crea una superclase llamada Sup y dos subclases de ella, llamadas Sub1 y Sub2. Sup declara que
un método llamado desde() y las subclases lo anulan. Dentro del método main(), se declaran los objetos de 3 Comentarios por Alex Walton
tipo Sup, Sub1 y Sub2. Además, se declara una referencia de tipo Sup, llamada referencia.
El programa luego asigna una referencia a cada tipo de objeto para referencia y usa esa referencia para llamar
a desde(). Como muestra en el resultado, la versión de desde() ejecutada, está determinada por el tipo de objeto al
que se hace referencia en el momento de la llamada, no por el tipo de clase de referencia.
Como se indicó anteriormente, los métodos reemplazados permiten a Java soportar el polimorfismo en tiempo de La palabra clave “final” se usa en diferentes contextos. En primer lugar, final es un modificador de no acceso
ejecución. El polimorfismo es esencial para la programación orientada a objetos por una razón: permite que una aplicable solo a una variable, un método o una clase. A continuación se muestran los contextos diferentes en los
clase general especifique los métodos que serán comunes a todas sus derivadas, al tiempo que permite que las que se utiliza .
subclases definan la implementación específica de algunos o todos esos métodos.
Los métodos reemplazados son otra forma en que Java implementa el aspecto de “una interfaz, múltiples Table de Contenido
métodos” del polimorfismo. Parte de la clave para aplicar con éxito el polimorfismo es comprender que las 1. Variables con Palabra Clave final
superclases y subclases forman una jerarquía que se mueve desde una especialización menor a una mayor. 1.1. Inicializar una variable final
1.2. Cuándo usar una variable final
Si se usa correctamente, la superclase proporciona todos los elementos que una subclase puede usar
directamente. También define los métodos que la clase derivada debe implementar por sí misma. Esto le permite a 1.3. Variable final de referencia
la subclase la flexibilidad de definir sus propios métodos, y aún aplica una interfaz consistente. Por lo tanto, al 1.4. Notas Importantes
combinar la herencia con la anulación de métodos/métodos reemplazados, una superclase puede definir la forma 2. Clases finales
general de los métodos que serán utilizados por todas sus subclases.
3. Métodos finales
Si la variable final es una referencia, esto significa que la variable no se puede volver a vincular para hacer
referencia a otro objeto, pero el estado interno del objeto apuntado por esa variable de referencia se puede
cambiar, es decir, puede agregar o eliminar elementos de la matriz final o colección final.
Es una buena práctica representar las variables finales en mayúsculas, utilizando guiones bajos para separar las
palabras.
Ejemplos:
1. Puede inicializar una variable final cuando se declara. Este enfoque es el más común. Una variable final se
llama variable final en blanco si no se inicializa en la declaración. // Programa Java para demostrar diferentes formas
2. Se puede inicializar una variable final en blanco dentro del bloque inicializador de instancias o dentro
del constructor. Si tiene más de un constructor en tu clase, debe inicializarse en todos ellos, de lo contrario se class JDC
3. Una variable estática final en blanco se puede inicializar dentro de un bloque estático.
// inicialización directa
// inicialización directa
CAPACIDAD = 25;
static{
CONSTANTEEULER = 2.3;
public JDC()
{
MINIMO = -1;
Como sabes, una variable final no se puede reasignar. Pero en el caso de una variable final de referencia, se puede class JDC {
cambiar el estado interno del objeto señalado por esa variable de referencia. Tenga en cuenta que esto no es una public static void main(String[] args) {
reasignación. Esta propiedad de final se llama no-transitividad. Para entender qué significa el estado interno del //variable local final
i=20;
class JDC {
}
20
System.out.println(cadena);
Tenga en cuenta la diferencia entre las variables const de C++ y las variables final de Java. Las
//cambiando estado interno de referencia del objeto
variables const en C++ deben tener un valor cuando se declaran. Para las variables final en Java, no es
//por variable de referencia final 'cadena'
necesario como vemos en los ejemplos anteriores. A una variable final se le puede asignar valor más
adelante, pero solo una vez.
cadena.append("desdeCero");
final dentro del bucle for-each: la declaración final en for-each es una declaración legal.
System.out.println(cadena);
}
//Programa Java para demostrar
class JDC {
int arr[]={1,2,3};
Java
for (final int i:arr)
JavadesdeCero System.out.println(i+"");
La propiedad no-transitividad también se aplica a las matrices, porque las matrices son objetos en Java. Las }
matrices con palabra clave final también se llaman matrices finales.
Salida:
1.4. Notas Importantes
1
Como se discutió anteriormente, una variable final no se puede reasignar, y arrojará un error en tiempo de 2
compilación. 3
CAPACIDAD=5;
}
Cuando una clase se declara con la palabra clave , se denomina clase final. Una clase final no se puede extender
} (heredar). Hay dos usos de una clase final:
Una es definitivamente evitar la herencia, ya que las clases finales no se pueden extender. Por ejemplo,
Salida:
todas las clases Wrapper como Integer, Float, etc. son clases finales. No podemos extenderlos.
Cuando se crea una variable final dentro de un método/constructor/bloque, se denomina variable final local, y
debe inicializarse una vez donde se crea. Ver a continuación el programa para la variable final local:
final class A
// métodos y campos
class B extends A
// COMPILACIÓN-ERROR!
El otro uso de final con clases es crear una clase inmutable como la clase String predefinida. No puede hacer
que una clase sea inmutable sin que sea definitiva.
3. Métodos finales
Cuando se declara un método con la palabra clave final, se denomina método final. Un método final no puede
ser anulado. La clase Object hace esto: varios de sus métodos son FINALES. Debemos declarar los métodos con
la palabra clave para la cual necesitamos seguir la misma implementación en todas las clases derivadas. El
siguiente fragmento ilustra la palabra clave final con un método:
class A
class B extends A
void m1()
// COMPILACIÓN-ERROR!
System.out.println("Ilegal!");
Para obtener más ejemplos y el comportamiento de los métodos finales y las clases finales, consulte: Uso de final
con herencia.