0% encontró este documento útil (0 votos)
46 vistas43 páginas

Java Apuntes Imprimir

1. El documento describe las clases, objetos, y cómo crear objetos en Java. Una clase define los atributos y comportamientos comunes a todos los objetos de ese tipo. Un objeto representa una instancia única de una clase con sus propios valores de atributo. Para crear un objeto, se usa el operador new para invocar el constructor de la clase y asignar memoria para el objeto.

Cargado por

Lara HTML5
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
46 vistas43 páginas

Java Apuntes Imprimir

1. El documento describe las clases, objetos, y cómo crear objetos en Java. Una clase define los atributos y comportamientos comunes a todos los objetos de ese tipo. Un objeto representa una instancia única de una clase con sus propios valores de atributo. Para crear un objeto, se usa el operador new para invocar el constructor de la clase y asignar memoria para el objeto.

Cargado por

Lara HTML5
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 43

1.

Qué es una Clase Identidad: nombre del perro

Estado/atributo: Color, Edad, Raza

Comportamiento: Dormir, comer, ladrar


Una clase es un modelo o prototipo definido por el usuario a partir del cual se crean los objetos. Representa el
conjunto de propiedades o métodos que son comunes a todos los objetos de un tipo. En general, las Los objetos corresponden a cosas que se encuentran en el mundo real. Por ejemplo, un programa de gráficos
declaraciones de clase pueden incluir estos componentes, en orden: puede tener objetos tales como “círculo”, “cuadrado”, “menú”. Un sistema de compra en línea podría tener
objetos como “carrito de compras”, “cliente” y “producto”.
Modificadores: una clase puede ser pública o tener acceso predeterminado (default). (Veremos otros
más adelante)
Nombre de clase: el nombre debe comenzar con una letra (en mayúscula por convención). 3. Declaración de objetos
Superclase (si corresponde): el nombre del elemento primario de la clase (superclase), si lo hay,
precedido por la palabra clave extends. Una clase solo puede extender (subclase) a uno de los padres.
Interfaces (si corresponde): una lista de interfaces separadas por comas implementadas por la clase, si Cuando declaramos objetos hablamos en términos de instanciar una clase. Cuando se crea un objeto de una
las hay, precedidas por la palabra clave implements. Una clase puede implementar más de una interfaz. clase, se dice que la clase está instanciada. Todas las instancias comparten los atributos y el comportamiento
Cuerpo: El cuerpo de la clase rodeado de llaves: {}. de la clase. Pero los valores de esos atributos, es decir, el estado son únicos para cada objeto. Una sola clase
puede tener cualquier cantidad de instancias.
Los constructores se utilizan para inicializar nuevos objetos. Los campos son variables que proporcionan el
estado de la clase y sus objetos, y los métodos se utilizan para implementar el comportamiento de la clase y sus
objetos.

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:

Perro clifford = new Perro("clifford","pitbull", 5, "blanco");

// Declaración de clase

System.out.println(clifford.toString());

public class Perro

}
{

// Variables de instancia

Salida:
String nombre;

String raza;

int edad;
Hola mi nombre es clifford.

String color; Mi raza, edad y color son: pitbull,5,blanco


// Declaración del constructor de clase


Esta clase contiene un solo constructor. Podemos reconocer un constructor porque su declaración usa el
public Perro(String nombre, String raza,
mismo nombre que la clase y no tiene un tipo de retorno (return). El compilador de Java diferencia los
int edad, String color)
constructores en función del número y el tipo de los argumentos. El constructor en la clase Perro toma cuatro
{
argumentos. La siguiente declaración proporciona a “clifford”, “pitbull”, 5, “blanco” como valores para esos
this.nombre = nombre;
argumentos:
this.raza= raza;

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

5. Maneras de crear el objeto de una clase


public String getRaza()

{
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

public int getEdad()


Ejemplo:

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.

// crear un objeto de public class Test

@Override

// considerar la clase Test presente en el paquete com.p1

public String toString()

Test obj = (Test)Class.forName("com.p1.Test").newInstance();


{

return("Hola mi nombre es "+ this.getNombre()+

".\nMi raza, edad y color son: " +


Usando el método clone(): el método clone() está presente en la clase Object. Crea y devuelve una
copia del objeto.
this.getRaza()+"," + this.getEdad()+

","+ this.getColor());

// creando el objeto de la clase Test

Test t1 = new Test ();


public static void main(String[] args)

// creación del clon del objeto anterior


btn.setOnAction(new EventHandler()

Test t2 = (Test)t1.clone(); {

public void handle(ActionEvent event)

Deserialización: Deserialización es la técnica de leer un objeto desde el estado guardado en un archivo. {

Hablaremos más adelante sobre Serialización/Des-serialización en Java. System.out.println("Hola Mundo!");

FileInputStream file = new FileInputStream(filename);


});
ObjectInputStream in = new ObjectInputStream(file);

Object obj = in.readObject();

6. Crear objetos múltiples solo por un tipo (Una


buena práctica)
En tiempo real, necesitamos diferentes objetos de una clase en diferentes métodos. Crear una serie de
referencias para almacenarlas no es una buena práctica y, por lo tanto, declaramos una variable de referencia
estática y la usamos siempre que sea necesario. En este caso, el desperdicio de memoria es menor. Los objetos
que ya no se referencia serán destruidos por el recolector de basura de Java. Ejemplo:

Test test = new Test();



test = new Test();

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 {}

class Dog extends Animal {}

class Cat extends Animal {}

public class Test


{

// usando el objeto Dog

Animal obj = new Dog();

// usando el objeto Cat

obj = new Cat();

7. Objetos anónimos
Los objetos anónimos son los objetos que se instancian pero no se almacenan en una variable de referencia.

Se usan para llamadas de método inmediato.


Serán destruidos después de llamar al método.
Son ampliamente utilizados en diferentes bibliotecas. Por ejemplo, en las bibliotecas AWT se utilizan para
realizar alguna acción al capturar un evento (por ejemplo, presionar una tecla).
En el siguiente ejemplo, cuando una tecla/botón (referido por btn) es presionada, simplemente estamos creando
un objeto anónimo de la clase EventHandler solo para llamar al método handle.

1. Cómo sobrecargar un método // Programa de demostración de sobrecarga de métodos

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. }

//Sobrecargando demoSobrec para un parámetro int

Los tipos de devolución no proporcionan información suficiente en todos los casos para que Java decida × void demoSobrec(int a){

qué método utilizar.


System.out.println("Un parámetro: " +a+"\n");

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){

System.out.println("Dos parámetros: "+a+", "+b);

return a+b;

//Sobrecargando demoSobrec para dos parámetros double

double demoSobrec(double a, double b){

System.out.println("Dos parámetros tipo double: "+a+", "+b);

return a+b;

class DemoSobrecarga{

public static void main(String[] args) {

Sobrecarga sc= new Sobrecarga();

int sumaint;

double sumadouble;

//Llamando todas las versiones de demoSobrec

sc.demoSobrec();

sc.demoSobrec(2);

sumaint=sc.demoSobrec(4,6);

System.out.println("Resultado de demoSobrec(4,6) es: "+sumaint+"\n");

sumadouble=sc.demoSobrec(1.1,2.2);

System.out.println("Resultado de demoSobrec(1.1,2.2) es: "+sumadouble);

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);

Resultado de demoSobrec(4,6) es: 10


}

Dos parámetros tipo double: 1.1, 2.2


}

Resultado de demoSobrec(1.1,2.2) es: 3.3000000000000003

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;

void demoSobrec(int a){


float f=11.5F;

System.out.println("Un parámetro: " +a);


}
sc.mitipo(i);


sc.mitipo(d);

int demoSobrec(int a){


System.out.println("Un parámetro: " +a);


sc.mitipo(b); //Conversión de tipo, llamando a sc.mitipo(int)

return a;
sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)

} sc.mitipo(f); //Conversión de tipo, llamando a sc.mitipo(double)

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

2. Conversiones de tipo automáticas Mi


Mi
tipo
tipo
(int): 10
(double): 11.5

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)

void mitipo (byte x){


Considere la función de valor absoluto. En los lenguajes que no admiten la sobrecarga, usualmente hay tres o
System.out.println("Mi tipo (byte): "+x);
más versiones de esta función, cada una con un nombre ligeramente diferente. Por ejemplo, en C, la
}
función abs() devuelve el valor absoluto de un entero, labs() devuelve el valor absoluto de un entero largo,

y fabs() devuelve el valor absoluto de un valor de coma flotante. Como C no admite sobrecarga, cada función
void mitipo (int x){

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{

public static void main(String[] args) {

Sobrecarga sc= new Sobrecarga();


¿Qué es el término firma utilizado por los programadores de Java?

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);

sc.mitipo(b); //NO HAY CONVERSION DE TIPO

¿Podemos sobrecargar los métodos que difieren solo por palabra clave static?
sc.mitipo(s); //Conversión de tipo, llamando a sc.mitipo(int)

sc.mitipo(f); //Conversión de tipo, llamando a sc.mitipo(double)


No podemos sobrecargar dos métodos en Java si difieren solo por palabra clave static (si el número
}
de parámetros y tipos de parámetros es el mismo).
}

Salida: ¿Cuál es la diferencia entre Overloading y Overriding?

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.

Ejemplo: Sobrecarga del método main


3. Introducción a Polimorfismo
La sobrecarga de métodos soporta el polimorfismo porque es una de las formas en que Java implementa el
paradigma de “una interfaz, múltiples métodos“.
class DemoSobrecarga{

// El método main()

Objetos y Métodos en Java


public static void main(String[] args) {

System.out.println("Hola Javeros (desde el main)");


En Java, todo es un objeto. ¿Qué es un objeto? Es una entidad que describe su estado con algunas variables y su
DemoSobrecarga.main("Java");
comportamiento con funciones/métodos. Veamos un ejemplo del mundo real.
}


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) {

y parar. Escribamos este código en Java en un archivo llamado  car.java :


System.out.println("Hola, " + arg1);

DemoSobrecarga.main("Java desde Cero","Sobrecarga de métodos");

}
public class Car {

public static void main(String arg1, String arg2) {


int speed;

System.out.println("Hola, " + arg1 + ", " + arg2);


int maxSpeed;

} 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:

5. Conclusión public static void main(String[] args) {

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.

Ahora ejecuta los siguientes comandos en la consola:


Por lo tanto, aunque puede usar el mismo nombre para sobrecargar métodos no relacionados, no debería ×
hacerlo. 
javac Car.java

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):

Resultado en consola del método void main

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.

No nos centremos en esto por ahora.

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:

Ejecutar método main desde IntelliJ IDEA

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:

public static void main(String[] args) {

System.out.println("Hola Java desde Cero");

El resultado de la ejecución puede verse en la consola.

Estructura de paquetes en Java

Los creadores sugirieron nombrar estas carpetas como nombres de dominio de Internet (por


ejemplo,  es.javadesdecero ) para distinguirlas con precisión, pero no es necesario, puedes nombrarlas como
quieras.

Esto también facilita la importación de clases de otras personas a tu código:


En el código, teníamos la siguiente línea:
package es.javadesdecero;

import java.util.Random; // importamos la descripción de la clase del paquete java.util.


Random random = new Random();
public class Import {

public static void main(String[] args) {


¿Qué hace?
Random random = new Random();

System.out.println(random.nextInt()); // mostrar un número aleatorio


Aquí utilizamos la palabra clave  new  para crear un nuevo objeto a partir de su plantilla. Especificamos que en
}
nuestro código utilizaremos el nombre  random  para referirnos a este objeto. En la última línea llamamos al
} método  nextInt  que devuelve algún número a nuestro programa y luego pasamos el mismo número al
método  println  que ya lo imprime.
No hay ninguna definición de la clase Random en nuestro paquete, así que he utilizado la palabra
clave  import  para añadirla a nuestro programa. Ahora puedo trabajar con él. Usando la palabra clave  new  creo Vamos a intentar crear una clase para nuestro auto y definir su comportamiento:
un objeto aleatorio basado en la clase, que puedo usar en el código posterior. Luego llamo al método  nextInt  del
objeto, que describe el siguiente comportamiento del objeto: el objeto devuelve del método un número natural, que
genera aleatoriamente a su manera. No sabemos cómo ocurre exactamente, sólo sabemos que al llamar a este public class Car {

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");

usuario de este método sepa cómo funciona bajo el capó. }

void stop() {
System.out.println("Detenerse");

public static void main(String[] args) {

Car myCar = new Car();

myCar.start();

myCar.stop();

Ejecuta el código y ve lo que aparece en la consola.

Programa de número aleatorio de Java

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.

public class Car {

int speed;

int maxSpeed;

public Car(int speed, int maxSpeed) {

this.speed = speed;

this.maxSpeed = maxSpeed;

System.out.println("El objeto está listo");

void start() {

System.out.println("Empezar a conducir");

System.out.println(speed);

Ejemplo de creación objetos en Java


}

Ahora volvemos a nuestras variables de estado del objeto. void stop() {


System.out.println("Detenerse");

Tipos Primitivos en Java }

System.out.println(maxSpeed);

public static void main(String[] args) {

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();

Palabra clave Tipo Ejemplo }

boolean true o false (número de 8 bits) true }

byte Número de 8-bit 123


Hemos añadido un código especial a nuestro código: el constructor. Nos permite inicializar el objeto antes de
empezar a utilizarlo. Al crear el objeto, añadí dos números naturales en el método  main , que inicializan el estado
short Número de 16-bit 123 del objeto en consecuencia. En el constructor podemos especificar cualquier lógica a realizar al crear el
objeto.
int Número de 32-bit 123

long Número de 64-bit 123L

float Número de 32-bit 123.0f

double Número de 64-bit 123.0

char Número de 16-bit ‘a’


Las strings son descritas por la clase  String . Veamos qué excepciones hay para ellas:

var str = "Me detuve";

var srt2 = new String("Me detuve");

Esta es la única clase que podemos crear sin el operador  new .

Además, las strings pueden sumarse entre sí o con otros tipos primitivos, pero no restarse, dividirse, etc:

System.out.println("Empecé a conducir" + "en dirección a M1");

System.out.println("Empecé a conducir" + "en dirección a M1 con la velocidad " + speed);

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.

Operador Descripción Ejemplo

! Invierte el valor lógico de una función booleana !true será false

+ó– Indica el signo de un número -123


Ejemplo de constructor en Java
++ Añade uno al número var i = 5; i++; //i será igual a 6
Si ejecutas la aplicación, verás que además de las cadenas/strings, también se muestran números, justo los que
pasamos en el constructor. Ahora nuestro objeto está inicializado – tiene algún tipo de estado interno. — Resta uno del número var i = 5; i–; //i será igual a 4

Referencias y Tipos Primitivos


A continuación pasamos a los operadores que toman dos argumentos, llamados operadores binarios. Los
Ahora veamos la diferencia clave entre las referencias a objetos, que usamos para trabajar con objetos, y los tipos operadores binarios son los más comunes en Java. Anteriormente hemos visto el operador de suma para strings.
primitivos. Para las referencias podemos escribir así:
Pueden utilizarse para realizar operaciones matemáticas con variables, crear expresiones lógicas y realizar
asignaciones básicas de variables.
var myCar = new Car(100, 500);

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)

/ División var i = 5; var k = 6; System.out.println(i / k)


int x = null;
% Tomando el módulo var i = 15; var k = 6; System.out.println(i % k)
Este tipo de código provocará un error.

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) {

verdadero ( true ) o falso ( false ): this.speed = speed;

else {

Operador Descripción Ejemplo System.out.println("Has recorrido demasiada velocidad");

var i = 5; var k = 6;
== Comparación de la igualdad }
System.out.println(i == k)

< ó <= Menor o menor igual


var i = 5; var k = 6;
System.out.println(i < k)
Bucles
var i = 5; var k = 6; ¿Qué debemos hacer si queremos repetir un bloque de código muchas veces? Si escribimos  while  en lugar
> ó >= Mayor, o mayor igual
System.out.println(i >= k) de  if  obtenemos el bucle más simple que se ejecutará mientras la expresión entre paréntesis sea verdadera o el
bucle no se rompa usando la palabra clave  break , o hasta que el programa termine, por ejemplo, desde otro hilo.
Operador and (y). Ambas partes deben ser true System.out.println(true Este es el aspecto que tendrá:
&&
para que el operador devuelva true && true)

Operador or (o). Al menos una parte debe ser System.out.println(false || public static void main(String[] args) {

|| var myCar = new Car(100, 500);

true para que el operador devuelva true true)


var i = 0;

while (i < 10){

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.

void setSpeed(int speed) {


Si no pasamos ninguna condición, obtendremos un bucle sin fin:
if (speed < maxSpeed) {

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);

Arrays y Colecciones (ArrayList) 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();

var myCar = new Car(100, 500);


}
var myCar2 = new Car(10, 50);

var garage = new Car[2];


A continuación, sustituye la primera línea por:

garage[0] = myCar;

var garage = new ArrayList<Car>();


garage[1] = myCar2;

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) {

recuperar esos objetos por una clave única:


car.start();

}
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);

garage.put("Mi segundo auto", myCar2);

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.

var myCar = new Car(100, 500);


Puedo decirte que las colecciones son algo que siempre utilizarás en tu trabajo, así que tienes que conocerlas.
var myCar2 = new Car(10, 50);
Aquí he cubierto sólo tres de ellos, que se utilizan el 99% de las veces, sin explicar qué métodos adicionales llevan.
var garage = new ArrayList<Car>();

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

Para declarar una colección, lo escribimos así:


at ru.proglib.Car.main(Car.java:42)

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){

System.out.println("No hay ningún auto con esta clave en el diccionario");


La toma de decisiones en la programación es similar a la toma de decisiones en la vida real. En la programación
} también enfrentamos algunas situaciones en las que queremos que se ejecute cierto bloque de código cuando
se cumple alguna condición.
Después de “ try “, escribo código entre llaves, de lo cual no estoy seguro. En el bloque de paréntesis “ catch ”
especifico qué tipo de errores pueden ocurrir. Los errores también son objetos en java. En consecuencia, en llaves Un lenguaje de programación utiliza instrucciones de control para controlar el flujo de ejecución del programa
especifico la lógica que se ejecutará cuando se produzca una excepción. en función de ciertas condiciones. Estos se utilizan para hacer que el flujo de ejecución avance y se ramifique en
función de los cambios en el estado de un programa.

Declaraciones de selección de Java:

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)

// Declaraciones para ejecutar si

// 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; {

declaracion2; // Ejecuta este bloque si


// la condición es verdadera

// Aquí si la condición es verdadera, el bloque if


}

// solo  considerará que la declaracion1 está dentro


else

// de su bloque. {

// Ejecuta este bloque si

Ejemplo: // la condición es falsa

// Programa Java para ilustrar la declaración If

Ejemplo:
class IfDemo

public static void main(String args[])


// Programa Java para ilustrar la declaración if-else

{
class IfElseDemo

int i = 10;
{


public static void main(String args[])

if (i > 15)
{

System.out.println("10 es menor que 15");


int i = 20;

// Esta declaración se ejecutará


if (i < 15)

        // como si considerara una declaración por defecto


System.out.println("Soy menor que 15");

System.out.println("No estoy en IF");


else

}
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 {

// Ejecuta cuando condicion1 es verdadero

2. if-else if (condition2)

// Ejecuta cuando condicion2 es verdadero

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:

// Programa Java para ilustrar declaraciones anidadas


// Programa Java para ilustrar if-else-if ladder

class NestedIfDemo
class ifelseifDemo

{
{

public static void main(String args[])


public static void main(String args[])

{
{

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("soy menor que 15");


else if (i == 20)


System.out.println("i es 20");

// Declaración if anidada
else

            // Solo se ejecutará si la instrucción anterior


System.out.println("i no está presente");

            // 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;

sentencia final else. break;

case value2:

declaracion2;

if (condición)
break;

declaración; .

else if (condición)
.

declaración; case valorN:

.
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:

// Programa Java para ilustrar usando

System.out.println("i es cero.");

// break para salir del bucle

break;

class BreakLoopDemo

case 1:

System.out.println("i es uno.");

public static void main(String args[])

break;

case 2:

// Inicialmente, el bucle está configurado para ejecutarse desde 0-9

System.out.println("i es dos.");

for (int i = 0; i < 10; i++)

break;

default:

// termina el bucle cuando llega a 5.

System.out.println("i es mayor que 2.");

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

control a otra parte del programa. i: 2

i: 3

6.1. break i: 4

Bucle completo.

En Java, break se utiliza principalmente para:


Usar break como una forma de Goto
1. Terminar una secuencia en una instrucción switch (discutida arriba). Java no tiene una declaración goto porque proporciona una forma de bifurcar de manera arbitraria y no
estructurada. Java usa etiquetas. Una etiqueta se usa para identificar un bloque de código.
2. Para salir de un bucle
Sintaxis:
3. Como una forma “civilizada” de goto.

Usar break para salir de un bucle etiqueta:

Utilizando el break, podemos forzar la terminación inmediata de un bucle, evitando la expresión condicional y
declaracion1;

cualquier código restante en el cuerpo del bucle.


declaracion2;

declaracion3;

Ahora, la instrucción break se puede utilizar para saltar fuera del bloque objetivo. Así:

// Programa Java para ilustrar usando

// continue en una declaración if

Nota: No puede romper ninguna etiqueta que no esté definida para un bloque envolvente. class ContinueDemo

public static void main(String args[])

for (int i = 0; i < 10; i++)

Ejemplo: {

// Si el número es par

// omitir y continuar

// Programa Java para ilustrar el uso de break con goto

if (i%2 == 0)

class BreakLabelDemo

continue;

public static void main(String args[])

// Si el número es impar, imprímalo

System.out.print(i + " ");

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á.");

// Programa Java para ilustrar usando return

}
class Return

System.out.println("Esto no se ejecutará.");

public static void main(String args[])

// Tercer bloque

boolean t = true;

System.out.println("Esto es después del segundo bloque.");

System.out.println("Antes de return.");

if (t)

}
return;

Salida: // El compilador eludirá todas las declaraciones

// después de return

Antes de la sentencia break


System.out.println("Esto no se ejecutará.");

Esto es después del segundo bloque. }

6.2. Continue Salida:

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.

Un bucle en lenguajes de programación es una característica que facilita la ejecución de un conjunto de


instrucciones/funciones repetidamente, mientras que algunas condiciones se evalúan como verdaderas.

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:

while (condición booleana)

declaraciones del bucle ...

Diagrama de flujo: Bucle while en Java

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)

// Programa Java para ilustrar el bucle while


{

class whileLoopDemo
declaracion(es)

{
}
public static void main(String args[])

int x = 1;

// Salir cuando x llega a ser mayor que 4

while (x <= 4)

System.out.println("Valor de x: " + x);

//incrementa el valor de x para la siguiente iteración

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.

4. Incremento/Decremento: se usa para actualizar la variable para la siguiente iteración.

5. Terminación de bucle: cuando la condición se vuelve falsa, el bucle termina marcando el final de su ciclo de
vida.

Ejemplo:

// Programa Java para ilustrar el bucle for.

class forLoopDemo
{

public static void main(String args[])

// bucle for comienza cuando x=2

ⓘ // y corre hasta x <=4

Sintaxis: for (int x = 2; x <= 4; x++)

System.out.println("Valor de x: " + x);

Salida:
Valor de x: 2

Valor de x: 3
Nota para leer
Valor de x: 4
Bucle for en Java (Puntos importantes)

2.1. Bucle for mejorado (for each) IR AL ARTÍCULO

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).

for (Elemento T:Colección de obj/array)

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:

El bucle mejorado (enhanced) de for simplifica el trabajo de la siguiente manera:

// Programa Java para ilustrar bucle for mejorado

public class Enhancedforloop

public static void main(String args[])

Diagrama de Flujo: Bucle do while en Java


{

String array[] = {"Ron", "Harry", "Hermoine"};

1. El bucle do while comienza con la ejecución de la(s) declaración(es). No hay verificación de ninguna


//mejorado para for
condición la primera vez.
for (String x:array)

{
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.
{

public static void main(String args[])

{
//Programa Java para la excepción de falta de memoria.

int x = 21;
import java.util.ArrayList;

do
public class Integer1

{
{

//El código dentro del do se imprime incluso


public static void main(String[] args)

//si la condición es falsa


{

System.out.println("Valor de x :" + x);


ArrayList<Integer> ar = new ArrayList<>();

x++;
for (int i = 0; i < Integer.MAX_VALUE; i++)

}
{

while (x < 20);


ar.add(i);

}
}

} }

}
Salida:
Salida:

Valor de x: 21
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

at java.util.Arrays.copyOf(Unknown Source)

4. Errores de bucles: Bucle infinito 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 

//Programa Java para ilustrar varias trampas de bucles.

public class LooppitfallsDemo

public static void main(String[] args)

// bucle infinito porque la condición no es apta

// la condición; debería haber sido i>0.

for (int i = 5; i != 0; i -= 2)

System.out.println(i);

int x = 5;

// bucle infinito porque la actualización

// 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.

La estructura del bucle for básico: // Programa Java para ilustrar

// Inicializando múltiples variables

// en el bloque de inicio

for(Inicialización; expresión booleana; declaración de actualización)

public class Example2

//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;

for(long y = 0, z = 4; x < 10 && y < 10; x++, y++)

Table de Contenido {

System.out.println(y + " ");

1. Proporcionar expresión en for es obligatorio


}

2. Inicialización de múltiples variables

3. Redeclaración de una variable en el bloque de inicialización System.out.println(x);

4. Las variables declaradas en el bloque de inicialización deben ser del mismo tipo }

5. Las variables en el bucle solo son accesibles en su interior }

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

// Programa Java para ilustrar

// 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í.
{

System.out.println("Este es un ciclo infinito");

}
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

Este es un ciclo infinito

...

2. Inicialización de múltiples variables

// Programa Java para ilustrar


// Programa Java para ilustrar

// redeclarar una variable


// redeclar una variable

// en el bloque de inicialización
// en el bloque de inicialización

public class Example3


public class Example3

{
{

public static void main(String[] args)


public static void main(String[] args)

{
{

// x es integer
// x es integer

int x = 0;
int x = 0;


long y = 10;

// redeclarando x como long no trabajará


for(long y = 0, x = 1; x < 5; x++)


for (y = 0, x = 1; x < 5; x++)

{
{

System.out.print(x + " ");


System.out.print(x + " ");

}
}

}
}

} }

Salida: Salida:

1 2 3 4

4. Las variables declaradas en el bloque de


inicialización deben ser del mismo tipo
Es simplemente un sentido común que cuando declaramos una variable como  ambas variables son del mismo
tipo. Lo mismo sucede en el bloque de inicialización.

Ejemplo:


// Programa Java para ilustrar

Example3.java:12: error: variable x is already defined in method main(String[])


// declarando una variable

for(long y = 0, x = 1; x < 5; x++) // en el bloque de inicialización

public class Example4

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. {

public static void main(String[] args)

Pero este problema se puede solucionar modificando ligeramente el código. Aquí, las variables x y y se declaran {

de una  manera diferente. // Esto causará error;

// int x;
Ejemplo:

// redeclarando x no long no funcionará

for (long y = 0, x = 1; x < 5; x++)

System.out.print(x + " ");

}
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:

// Programa Java para ilustrar el

// declaración de switch

// alcance de Inicializar variables

switch(expresión)
// dentro del bucle

public class Example5

// declaración case

// los valores deben ser del mismo tipo de la expresión

public static void main(String[] args)

case valor1 :

// Declaraciones

// "x" y "y" solo son de alcance

break; // break es opcional

// dentro del bucle for

for(int x = 0, y = 0; x < 3 && y < 3; x++, y++)

case valor2 :

// Declaraciones

System.out.println(y + " ");

break; // break es opcional

// Podemos tener cualquier número de declaraciones de casos o case

System.out.println(x);

// debajo se encuentra la declaración predeterminada, que se usa cuando ninguno de los casos e
}

// No se necesita descanso en el case default

}
default :

// Declaraciones

Salida: }

Example5.java:13: error: cannot find symbol

System.out.println(x); Diagrama de Flujo de Switch-case:

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.

// rograma Java para demostrar switch case

// con tipo de datos primitivos (int)

public class Test

public static void main(String[] args)

int day = 5;

String dayString;

// instrucción switch con tipo de datos int

switch (day)

case 1: dayString = "Lunes";

break;

case 2: dayString = "Martes";

break;

case 3: dayString = "Miercoles";

break;

case 4: dayString = "Jueves";

break;

case 5: dayString = "Viernes";

break;

case 6: dayString = "Sabado";

break;

case 7: dayString = "Domingo";

break;

default: dayString = "Dia inválido";

break;

System.out.println(dayString);

Salida:

Diagrama de Flujo de Switch-case Java

Algunas reglas importantes para declaraciones switch:

Los valores duplicados de los case no están permitidos.


El valor para un case debe ser del mismo tipo de datos que la variable en el switch.
El valor para un case debe ser una constante o un literal. Las variables no están permitidas.
La declaración break se usa dentro del switch para finalizar una secuencia de instrucción. ⓘ
La declaración break es opcional. Si se omite, la ejecución continuará en el siguiente case.
La instrucción default es opcional, y debe aparecer al final del switch. Viernes

2. Ejemplos de Switch case 2.1. Omitir la declaración break


Como la declaración break es opcional. Si omitimos el break, la ejecución continuará en el siguiente case. A Salida:
veces es deseable tener múltiples case sin declaraciones break entre ellos. Por ejemplo, considere la versión
actualizada del programa anterior, también muestra si un día es un día laborable o uno de fin de semana.
Martes es un Dia laborable

// Programa Java para demostrar switch case

// con multiples casos sin declaraciones break


3. Declaraciones anidadas de Switch Case
public class Test

public static void main(String[] args)


Podemos usar un switch como parte de la secuencia de la declaración de un switch externo. Esto se llama
{
un switch anidado. Como una instrucción de switch define su propio bloque, no surgen conflictos entre las
constantes de case en el switch interno y las del switch externo. Por ejemplo:
int day = 2;

String dayType;

String dayString;
// programa de Java para demostrar


// declaracines switch case anidadas

switch (day)
public class Test

{
{

case 1: dayString = "Lunes";


public static void main(String[] args)

break;
{

case 2: dayString = "Martes";


String Branch = "CSE";

break;
int year = 2;

case 3: dayString = "Miercoles";


break;
switch(year)

case 4: dayString = "Jueves";


{

break;
case 1 :

case 5: dayString = "Viernes";


System.out.println("Cursos electivos: Ingles, Calculo");

break;
break;

case 6: dayString = "Sabado";


case 2:

break;
switch (Branch) // switch anidado

case 7: dayString = "Domingo";


{
break;
case "CSE":

default: dayString = "Dia invalido";


case "CCE":

}
System.out.println("Cursos electivos : Machine Learning, Big Data");


break;

switch (day)

{
case "ECE":

//multiples cases sin declaraciones break


System.out.println("Cursos electivos : Programacion");

break;

case 1:

case 2:
default:

case 3:
System.out.println("Cursos electivos : Ingenieria de Software");

case 4:
}
case 5:
}

dayType = "Dia laborable";


}

break;
}
case 6:

case 7:
Salida:
dayType = "Fin de semana";

break;

Cursos electivos : Machine Learning, Big Data


default: dayType= "Tipo de dia invalido";

4. String en Switch Case


System.out.println(dayString+" es un "+ dayType);

}
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:

// Programa Java para demostrar el uso de un

// string para controlar una declaracion switch

public class Test

public static void main(String[] args)

String str = "dos";

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! {

private static Object obj;

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;

System.out.println("El valor del objeto obj es : " + obj);

A continuación se detallan algunos puntos importantes sobre null en Java que todo programador de Java debe
saber: }

Table de Contenido Salida:


1. null es Case sensitive
2. Valor de variable de referencia El valor del objeto obj es : null
3. Tipo de null
4. Autoboxing y unboxing
5. Operador instanceof 3. Tipo de null
6. Métodos estáticos vs no estáticos
7. == y != A diferencia de la idea errónea común, null no es un objeto ni un tipo. Es solo un valor especial, que se puede
asignar a cualquier tipo de referencia y se puede castear null a cualquier tipo.

1. null es Case sensitive Ejemplos:

// null se puede asignar a String

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;

// tambien puedes asignar null a Integer

public class Test Integer itr = null;

public static void main (String[] args) throws java.lang.Exception


// null también se puede asignar a Double

{
Double dbl = null;

// error en tiempo de compilación: no se puede encontrar el símbolo 'NULL'


Object obj = NULL;


//null se puede castear a String


String myStr = (String) null;

//lo siguiente se ejecuta con éxito


Object obj1 = null;


// también puede ser casteado a Integer

}
Integer myItr = (Integer) null;

// si es posible, no hay error

Salida: Double myDbl = (Double) null;

error: cannot find symbol

can't find symbol '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

2. Valor de variable de referencia


Cualquier variable de referencia en Java tiene un valor predeterminado nulo.

false

true

ⓘ 6. Métodos estáticos vs no estáticos


public class Test
{
No podemos llamar a un método no estático en una variable de referencia con valor nulo,
public static void main (String[] args) throws java.lang.Exception
arrojará NullPointerException, pero podemos llamar al método estático con variables de referencia con valores
nulos.
{

//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;

//Unboxing null a integer lanza NullpointerException


public class Test
int a = i;
{

}
public static void main(String args[])

} {

Test obj= null;

Salida: obj.staticMethod();

obj.nonStaticMethod();

Exception in thread "main" java.lang.NullPointerException

at Test.main
private static void staticMethod()

5. Operador instanceof //Puede ser llamado por referencia nula

System.out.println("metodo estatico, puede ser llamado por referencia nula");

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

expresión no es nulo. private void nonStaticMethod()

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

conversión de tipo. System.out.print(" Metodo no estatico- ");

System.out.println("no puede ser llamado por referencia nula");

Ejemplo:

public class Test

{
}
public static void main (String[] args) throws java.lang.Exception

{
Salida:
Integer i = null;

Integer j = 10;

Exception in thread "main" java.lang.NullPointerException

at Test.main

//imprime false

System.out.println(i instanceof Integer);

metodo estatico, puede ser llamado por referencia nula


//Compila con exito

System.out.println(j instanceof Integer);


7. == y !=
}
Esto puede ser útil en la comprobación de null con objetos en Java.
Salida:
public class Test
{

1. ¿Qué es un Método en Java?


public static void main(String args[])

{
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.

} 2. ¿Cómo se escribe un método?


Salida:
Un método tendrá paréntesis después de su nombre. Por ejemplo, si el nombre de un método es getval, se
escribirá getval() cuando su nombre se usa en una sentencia. Esta notación lo ayudará a distinguir los nombres
true
de las variables de los nombres de los métodos.
false
La forma general de un método se muestra a continuación:

tipo-retorno nombre(lista parámetros){

//Cuerpo del método

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:

/* Un programa que usa la clase Vehiculo


//Añadiendo rango a Vehiculo

El archivo se llama DemoVehiculo.java


*/
class Vehiculo {

class Vehiculo {
int pasajeros; //números de pasajeros

int pasajeros; //números de pasajeros


int capacidad; //capacidad del combustible en galones

int capacidad; //capacidad del combustible en galones


int mpg; //combustible consumido en millas por galon

int mpg; //combustible consumido en millas por galon


}
//Mostrando el rango

//Esta clase declara un objeto de tipo Vehiculo


void rango (){

class DemoVehiculo {
System.out.println("Con rango de "+ capacidad*mpg);

public static void main(String[] args) {


}

Vehiculo minivan = new Vehiculo();


}

int rango;

//asignando valores a los campos de minivan


class MetodoAdicional {

minivan.pasajeros = 9;

minivan.capacidad = 15;
public static void main(String[] args) {

minivan.mpg = 20;
Vehiculo minivan = new Vehiculo();

//Calcular el rango asumiendo un tanque lleno


Vehiculo sportscar = new Vehiculo();

rango = minivan.capacidad * minivan.mpg;


System.out.println("La Minivan puede llevar " + minivan.pasajeros + " pasajeros con un ra

}
//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;

es la mejor manera de manejar este cálculo.


sportscar.capacidad=25;

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();

Este programa genera la siguiente salida:

La Minivan puede llevar 9. Con rango de 300

El Sportscar puede llevar 9. Con rango de 750

4. Entendiendo el funcionamiento del Método


Veamos los elementos clave de este programa, comenzando con el método :

La primera línea de rango() es


Cuando se ejecuta esta instrucción, el control del programa regresa a quién lo llama, omitiendo cualquier código
void rango() {
restante en el cuerpo del método. Por ejemplo, considere este método:
//Esta línea declara un método llamado rango que no tiene parámetros.

//Su tipo de devolución es void, osea nulo.

//Por lo tanto, rango() no devuelve un valor al ser llamado.


void miMetodo(){

//La línea termina con la llave de apertura del cuerpo del método. int i;

for (i=0; i<10; 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);

System.out.println("Con rango de "+ capacidad*mpg);


}

//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 {

int pasajeros; //números de pasajeros

int capacidad; //capacidad del combustible en galones

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

//Retornando o devolviendo el rango


Aunque el programa anterior es correcto, no está escrito de la manera más eficiente posible. Específicamente,
int rango (){ no hay necesidad de las variables rango1 o rango2. Una llamada a rango() se puede usar en la
instrucción println() directamente, como se muestra aquí:
return capacidad*mpg;


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) {

Vehiculo minivan = new Vehiculo();

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.

//Asigando valores a los campos en minivan


Un parámetro está dentro del alcance de su método, y aparte de su tarea especial de recibir un argumento,
minivan.pasajeros=9;
actúa como cualquier otra variable local.
minivan.capacidad=15;

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 {

//Obteniendo los rangos


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 {

public static void main(String[] args) {

ComprobarNumero e=new ComprobarNumero();

Salida:

if (e.esPar(10)) System.out.println("10 es par.");

La Minivan puede llevar 9. Con rango de: 300


if (e.esPar(9)) System.out.println("9 es par.");

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){

if ((b%a)==0) return true;

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) {

Divisor x =new Divisor();

if (x.esDivisor(2,20)) System.out.println("2 es Divisor de 20");

if (x.esDivisor(3,20)) System.out.println("3 es Divisor de 20");

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.

Por ejemplo, esto es perfectamente válido:

int miMetodo(int a, double b, float c) {

// ...

//Un ejemplo siemple de constructor

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 {

public static void main(String[] args) {


int x;

MiClase t1= new MiClase();


MiClase t2= new MiClase();


MiClase(int i){


x=i;

System.out.println(t1.x + " - "+t2.x);


}

} }

En este ejemplo, el constructor de MiClase es: class ConstructorDemo {

public static void main(String[] args) {

MiClase(){
MiClase t1= new MiClase(15);

x=10;
MiClase t2= new MiClase(28);

System.out.println(t1.x + " - "+t2.x);

Este constructor asigna a la variable de instancia x de MiClase el valor de 10. Este constructor es llamado por }

new cuando se crea un objeto. Por ejemplo, en la línea: }

La salida de este programa es:

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(15);

se ejecuta, el valor 10 pasa a i, que luego se asigna a x.


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 {

int pasajeros; //números de pasajeros

int capacidad; //capacidad del combustible en galones

int mpg; //combustible consumido en miles por galon

//Esto es un constructor para Vehiculo

Vehiculo (int p, int c, int m) {

pasajeros=p;

capacidad=c;

mpg=m;

//Retornando el rango

int rango(){

return mpg*capacidad;

//Calcular el combustible necesario para una distancia dada

double capacidadnueva(int miles){

return (double)miles/mpg;

class DemoVehiculo {

public static void main(String[] args) {

Vehiculo minivan = new Vehiculo(9,15,20);

Vehiculo sportscar = new Vehiculo(10,25,30);

double galones;

int distancia = 250;

galones=minivan.capacidadnueva(distancia);

System.out.println("Para ir a "+distancia+" en minivan, se necesita "+galones+" galones")


galones=sportscar.capacidadnueva(distancia);

System.out.println("Para ir a "+distancia+" en sportscar, se necesita "+galones+" galones


}

Salida:

Para ir a 250 en minivan, se necesita 12.5 galones

Para ir a 250 en sportscar, se necesita 8.333333333333334 galones

Ambos, minivan y sportscar, son inicializados por el constructor Vehiculo() cuando se crean. Cada objeto se


inicializa como se especifica en los parámetros para el constructor. Por ejemplo, en la siguiente línea,

Vehiculo minivan = new Vehiculo(9,15,20);

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.1. Reglas de clase una interna local Externa$1Interna.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.

4. Una clase local tiene acceso a los miembros de su clase adjunta.

5. Las clases internas locales pueden extender una clase abstracta o también pueden implementar una interfaz.

Ya no es obligatorio ‘final’, siempre y cuando la variable no se modifique.

1.2. Declarar una clase interna local


Una clase interna local se puede declarar dentro de un bloque. Este bloque puede ser un cuerpo de método,
bloque de inicialización, bucle for o incluso una sentencia if.

1.3. Acceso a los miembros


Una clase interna local tiene acceso a los campos de la clase que lo incluye, así como a los campos del bloque
en el que está definido. Sin embargo, estas clases pueden acceder a las variables o parámetros del bloque que
lo incluye solo si se declaran como definitivas o si son efectivamente finales. Una variable cuyo valor no se
cambia una vez inicializada se denomina como variable final. Una clase interna local definida dentro de un
cuerpo de método tiene acceso a sus parámetros.

1.4. ¿Qué sucede en el momento de la compilación?


Cuando se compila un programa que contiene una clase interna local, el compilador genera dos archivos .class,
uno para la clase externa y el otro para la clase interna que tiene la referencia a la clase externa. Los dos
archivos son nombrados por el compilador como:
// Programa Java para ilustrar el funcionamiento
Nota: Una clase local puede acceder a variables y parámetros locales del bloque envolvente que son
// de las clases internas locales
efectivamente finales.  ×

//Clase externa

class ClaseExterna

private void getValor() {


Una variable o parámetro cuyo valor nunca se cambia después de que se inicializa es
//Tenga en cuenta que la variable local (suma) debe ser final --hasta JDK 7

efectivamente final.
// por lo tanto, este código solo funcionará en JDK 8

int suma = 20;

//Método dentro de clase interna interna

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;

Debido a esta declaración de asignación, la variable suma ya no es efectivamente final. Como resultado, el


}

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

private int getCociente(){

System.out.println("Dentro de la clase local.");


Ejemplo:
return suma/divisor;

Interna interna=new Interna();

System.out.println("Divisor: "+interna.getDivisor());

System.out.println("Resto: "+interna.getResto());

System.out.println("Cociente: "+interna.getCociente());

public static void main(String[] args) {

ClaseExterna externa=new ClaseExterna();

externa.getValor();

Salida:

Divisor: 4

Resto: 0

Dentro de la clase local.

Cociente: 5

// Programa Java para ilustrar el funcionamiento


// Programa Java para demostrar

// de las clases internas locales dentro de una declaración if


// que las clases internas no pueden ser declarados como static

//Clase externa
//Clase externa

class ClaseExterna
public class ClaseExterna

{
{

public int dato=10;


private int getValor(int dato)

public int getDato(){


static class Interna

return dato;
{

}
private int getDato()

public static void main(String[] args) {


System.out.println("Dentro de la clase interna.");

ClaseExterna externa=new ClaseExterna();


if(dato < 10)


{
if (externa.getDato()<20){
return 5;

// Clase interna local dentro de la cláusula if


}
class Interna{
else

public int getValor(){


{
System.out.println("Dentro de la clase interna.");
return 15;

return externa.dato;
}
} }

}
}

Interna interna=new Interna();


Interna interna = new Interna();

System.out.println(interna.getValor());
return interna.getDato();

}
}

else {

System.out.println("Dentro de la clase externa.");


public static void main(String[] args)

}
{

}
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

importante en muchos programas del mundo real.


{

private void miMetodo(){

class Interna{
1. Clases Anidadas o Nested Classes
private void metodoInterno(){

System.out.println("Dentro de la clase interna.");

}
¿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) {

clase anidada está limitado por su clase externa.


ClaseExterna externa= new ClaseExterna();
Una clase anidada también es miembro de su clase adjunta. También es posible declarar una clase
Interna interna=new Interna();
anidada que es local a un bloque.
System.out.println(interna.metodoInterno());
Como miembro de su clase adjunta, una clase anidada se puede declarar private, public, protected, o
}
default (Leer sobre Modificadores de acceso).
} Una clase anidada tiene acceso a los miembros, incluidos los miembros privados, de la clase en la que
está anidado. Sin embargo, lo inverso no es verdadero, es decir, la clase adjunta no tiene acceso a los
miembros de la clase anidada.
Salida: Hay dos tipos generales de clases anidadas: las que están precedidas por el modificador static (static
nested class) y las que no lo están (inner class).

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.

Clases Anidadas (Nested Classes)

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;

2. Clases anidadas estáticas

//Miembro privado

private static int externo_privado=30;

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

una referencia de objeto. static class ClaseAnidadaStatic{

void mostrar(){

//Puede acceder al miembro estático de la clase externa

System.out.println("externo_x: "+externo_x);

//Puede acceder a mostrar un miembro estático privado de la clase externa

System.out.println("externo_privado: "+externo_privado);

// La siguiente declaración dará error de compilación

// ya que la clase anidada estática no puede acceder directamente

// a un miembro no estático

// System.out.println ("externo_y =" + externo_y);

Se accede a ellos usando el nombre de la clase adjunta. Así:


class ClaseAndidadaStaticDemo {

public static void main(String[] args) {

ClaseExterna.ClaseAnidadaStatic

//Accediendo a la clase anidada estática

Por ejemplo, para crear un objeto para la clase anidada estática, use esta sintaxis: ClaseExterna.ClaseAnidadaStatic objetoAnidado= new ClaseExterna.ClaseAnidadaStatic();

objetoAnidado.mostrar();

ClaseExterna.ClaseAnidadaStatic objetoAnidado = new ClaseExterna.ClaseAnidadaStatic(); }

}
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

Sintaxis: static int externo_x=10;

//Miembro de instancia

clase ClaseExterior
int externo_y=20;

...
//Miembro privado

clase ClaseInterna
private int externo_privado=30;

...
class ClaseInterna{

} void mostrar(){

//Puede acceder al miembro estático de la clase externa

System.out.println("externo_x: "+externo_x);

Una instancia de ClaseInterna puede existir solo dentro de una instancia de ClaseExterior y tiene acceso ×

directo a los métodos y campos de su instancia adjunta.


//Puede acceder a un miembro no estático de la clase externa

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);

ClaseExterna objetoExterno=new ClaseExterna();


ClaseExterna.ClaseInterna objetoInterno= objetoExterno.new ClaseInterna(); }

Ejemplo: (Comparando el ejemplo con las Clases anidadas estáticas) }

class ClaseInternaDemo{

public static void main(String[] args) {

//Accediendo a la clase interna

ClaseExterna objetoExterno=new ClaseExterna();

ClaseExterna.ClaseInterna objetoInterno= objetoExterno.new ClaseInterna();

objetoInterno.mostrar();

Salida:

externo_x: 10

externo_y: 20

externo_privado: 30

Hay dos tipos especiales de clases internas:

Clases internas locales


Clases internas anónimas

2. Ejemplo de clases internas en Java


A veces, una clase interna se utiliza para proporcionar un conjunto de servicios que solo utiliza su clase adjunta.
Aquí hay un ejemplo que usa una clase interna para calcular varios valores para su clase adjunta:

// Programa Java para demostrar las clases internas

//Clase externa

class ClaseExterna {

int nums[];

ClaseExterna(int n[]){

nums=n;

void analizar(){

Interna inOb=new Interna();


System.out.println("Minimo: "+inOb.min());

Ejemplo:
System.out.println("Máximo: "+inOb.max());

System.out.println("Promedio: "+inOb.promedio());

//Esta es una clase interna

class Interna{

int min(){

int m=nums;

for (int i=1;i<nums.length;i++)

if(nums<m) m= nums;

return m;
}

int max(){

int m=nums;

for (int i=1; i<nums.length;i++)

if (nums>m) m=nums;

return m;
}

int promedio(){

int a=0;

for (int i=0; i<nums.length;i++)

a+=nums;

return a/nums.length;

class ClaseAndidadaDemo {

public static void main(String[] args) {

int x[]={3,2,1,5,6,7,8,9};

ClaseExterna extob= new ClaseExterna(x);

extob.analizar();

Salida:
Minimo: 1

Máximo: 9

1. La Palabra Clave this


Promedio: 5
Cuando se llama a un método, se pasa automáticamente un argumento implícito que es una referencia al objeto
En este ejemplo, la clase Interna calcula varios valores de los nums de la matriz, que es miembro invocado (es decir, el objeto sobre el que se llama el método). Esta referencia se llama this. Para comprender
de ClaseExterna. Como se explicó, una clase interna tiene acceso a los miembros de su clase envolvente, por lo esto, considere primero un programa que crea una clase llamada Potencia que calcula el resultado de un
que es perfectamente aceptable que Interna acceda directamente a la matriz nums. Por supuesto, lo opuesto no número elevado a una potencia entera:
es verdad. Por ejemplo, no sería posible que analizar() invoque el método min() directamente, sin crear un objeto
interno.
//Un ejemplo del uso de this

3. Diferencia entre clases estáticas e internas class Potencia {

(anidadas no estáticas) double b;


int e;

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

métodos estáticos y no estáticos, incluido el privado/private) de su clase externa y pueden referirse a


if (exp==0) return;

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 {

public static void main(String[] args) {

Potencia x=new Potencia(4.0,2);

Potencia y=new Potencia(2.5,1);

Potencia z=new Potencia(2.7,2);

System.out.println(x.b+ " elevado a la potencia de "+ x.e+", es igual a: "+x.get_potencia


System.out.println(y.b+ " elevado a la potencia de "+ y.e+", es igual a: "+y.get_potencia
System.out.println(z.b+ " elevado a la potencia de "+ z.e+", es igual a: "+z.get_potencia
}

Salida:

4.0 elevado a la potencia de 2, es igual a: 16.0

2.5 elevado a la potencia de 1, es igual a: 2.5

2.7 elevado a la potencia de 2, es igual a: 7.290000000000001

1.1. Uso de this en Java


Como sabe, dentro de un método, se puede acceder directamente a los otros miembros de una clase, sin ningún
objeto o calificación de clase. Por lo tanto, dentro de get_potencia(), la declaración return valor; significa que se
devolverá la copia del valor asociado con el objeto invocado. Sin embargo, la misma declaración también se

puede escribir así:


Potencia(double b, int e){

this.b=b;

return this.valor; this.e=e;

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.

2. Usar la palabra clave ‘this’ para referirse a las


variables de instancia de la clase actual
Ejemplo:

//Código Java sobre el uso de la palabra clave 'this' para


//referir las variables de instancia de la clase actual

A continuación se muestra toda la clase Potencia escrita usando la referencia this:


class Test

class Potencia {
int a;

double b; int b;

int e;

double valor;
// Constructor parametrizado


Test(int a, int b)

Potencia(double base, int exp){


{

this.b=base;
this.a = a;

this.e=exp;
this.b = b;

this.valor=1;
}

if (exp==0) return;
void display()

for ( ; exp>0; exp--) this.valor = this.valor * base;


{

}
//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)

} {

Test object = new Test(10, 20);

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

3. Usando this() para invocar al constructor de la


clase actual
Ejemplo:
//Código Java sobre el uso de laa palabra clave 'this'

//para devolver la instancia de la clase actual

// Código Java sobre el uso de this() para


class Test

// invocar al constructor de la clase actual


{

class Test
int a;

{
int b;

int a;

int b;
//Constructor predeterminado


Test()

//Constructor predeterminado
{

Test()
a = 10;

{
b = 20;

this(10, 20);
}

System.out.println("Dentro del constructor predeterminado \n");


}
//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("Dentro del constructor parametrizado");


void display()

}
{


System.out.println("a = " + a + " b = " + b);

public static void main(String[] args)


}

Test object = new Test();


public static void main(String[] args)

}
{

} Test object = new Test();

object.get().display();

Salida: }

Dentro del constructor predeterminado

Salida:
Dentro del constructor parametrizado

4. Usar la palabra clave ‘this’ para devolver la


a = 10 b = 20

instancia de clase actual 5. Usar la palabra clave ‘this’ como parámetro de


Ejemplo:
método
Ejemplo:

// Código de Java para usar 'this'


// Código Java sobre el uso de 'this' para invocar

// como parámetro de método


// el método de clase actual

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");

// Método que recibe 'this' como parámetro


}

void display(Test obj)


System.out.println("a = " + a + " b = " + b);


public static void main(String args[]) {

}
Test t1 = new Test();


t1.display();

// Método que devuelve la instancia de la clase actual


}

void get()
}
{

display(this);
Salida:
}

public static void main(String[] args)


Dentro del método show

Dentro del método display


{

Test object = new Test();

object.get();

7. Usar la palabra clave ‘this’ como argumento en la


} llamada de constructor
Salida:
Ejemplo:

a = 10 b = 20

6. Usar la palabra clave ‘this’ para invocar método


de la clase actual
Ejemplo:
// Código Java para usar 'this' como un argumento
Un array o matriz es simplemente una variable que puede contener valores múltiples, a diferencia de una
// en la llamada de constructor class A
variable regular que solo puede contener un único valor.
// con el objeto de class B como su miembro de datos

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.

La superclase directa de un tipo de array es Object.


// llamando al método display de class B
Cada tipo de array implementa las interfaces Cloneable y java.io.Serializable.
obj.display();
El array puede contener tipos de datos primitivos así como también objetos de una clase según la
}
definición del array. En el caso de los tipos de datos primitivos, los valores reales se almacenan en

ubicaciones de memoria contigua. En el caso de los objetos de una clase, los objetos reales se
}
almacenan en heap.

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;

//Constructor predeterminado que crea un objeto de A


Table de Contenido
//pasando 'this' como un argumento en el constructor
1. Qué es un Array en Java
B()
2. Arrays unidimensionales
{

2.1. Instanciando un array en Java


A obj = new A(this);

2.2. Array Literal


}


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
}

3.3. Objectos Class para arrays


5. Asignación de referencias en Arrays


public static void main(String[] args) {

B obj = new B();


6. Clonación de arrays
}
7. Uso de length en Arrays
}

Salida: 1. Qué es un Array en Java


Valor de x en Class B: 5 Una array o arreglo es una colección de variables del mismo tipo, a la que se hace referencia por un nombre
común. En Java, los arrays pueden tener una o más dimensiones, aunque el array unidimensional es el más
común.

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.

// ambas son declaraciones válidas

int intArray[];

int[] intArray;

//Tipo de datos primitivos

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

// la clase MyClass (una clase creada por

 
// el usuario)

2. Arrays unidimensionales MyClass myClassArray[];

Object[] ao, // array de Object

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…

tipo nombre-array[]; 2.1. Instanciando un array en Java


o Cuando un array se declara, solo se crea una referencia del array. Para realmente crear o dar memoria al array
(a partir de aquí solo mencionaré a array, y no matriz o arreglo), puede crear un array de la siguiente manera:
tipo [] nombre-array;
nombre-array = new tipo ;
La declaración de un array tiene dos componentes: el tipo y el nombre.
tipo especifica el tipo de datos que se asignará
tipo declara el tipo de elemento del array. El tipo de elemento determina el tipo de datos de cada tamaño especifica el número de elementos en el array
elemento que comprende la matriz. Al igual que la matriz de tipo int, también podemos crear una matriz de nombre-array es el nombre de la variable del array vinculado al mismo.
otros tipos de datos primitivos como char, float, double..etc o tipo de datos definido por el usuario (objetos Es decir, para usar new para asignar un array, debe especificar el tipo y la cantidad de elementos a
de una clase). Por lo tanto, el tipo de elemento para la matriz determina el tipo de datos que la matriz asignar.
contendrá.
Ejemplo:
Ejemplo:

int intArray[]; //declarando un array

intArray = new int; // asignando memoria al array

int[] intArray = new int; // combinando ambas declaraciones en una

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

2.2. Array Literal public static void main (String[] args)

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;

int[] intArray = new int[]{ 1,2,3,4,5,6,7,8,9,10 };

// asignando memoria para 5 enteros.

// Declarando un array literal


arr = new int;

La longitud de este array determina la longitud del array creado. // inicializa el primer elemento del array

No es necesario escribir new int[] en las últimas versiones de Java


arr = 10;

2.3. Accediendo a los elementos del Array usando el bucle for

// inicializa el segundo 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;

//acceder a los elementos del array


arr = 40;

for (int i = 0; i < arr.length; i++)


arr = 50;

System.out.println("Elemento en el índice " + i + " : "+ arr);

// accediendo a los elementos del array

Ejemplo: for (int i = 0; i < arr.length; i++)

System.out.println("Elemento en el índice " + i +

" : "+ arr);

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  ×

2.4. Arrays de objetos


Se crea una matriz de objetos como una matriz de elementos de datos de tipo primitivo de la siguiente manera.

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:

// Programa Java para ilustrar la creación de

// 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;

public String name;

Student(int roll_no, String name)


int[][] intArray = new int; //un array 2D o matrix

{
int[][][] intArray = new int; //una array 3D
this.roll_no = roll_no;

this.name = name;
Ejemplo:
}


class multiDimensional

// Los elementos del array son objetos de la clase Student


{

public class DemoArray2


public static void main(String args[])

{
{

public static void main (String[] args)


// declarar e inicializar array 2D

{
int arr[][] = { {2,7,9},{3,6,1},{7,4,2} };

// declara una array de enteros.


Student[] arr;
// imprimir array 2D


for (int i=0; i< 3 ; i++)

// asigna memoria para 5 objetos del tipo Student.


{

arr = new Student;


for (int j=0; j < 3 ; j++)


System.out.print(arr + " ");

// inicializa el primer elemento del array


arr = new Student(1,"uno");


System.out.println();

// inicializa el segundo elemento del array


}

arr = new Student(2,"dos");


}

// y así...
Salida:
arr = new Student(3,"tres");

arr = new Student(4,"cuatro");

2 7 9

arr = new Student(5,"cinco");

3 6 1

7 4 2
// accediendo a los elementos del array

for (int i = 0; i < arr.length; i++)

System.out.println("Elemento en " + i + " : " +


3.1. Pasar arrays a métodos
arr.roll_no +" "+ arr.name);

}
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?

El compilador arroja ArrayIndexOutOfBoundsException para indicar que se ha accedido al array con un índice


ilegal. El índice es negativo, mayor o igual que el tamaño del array.
// Programa Java para demostrar
// Programa Java para demostrar

// el uso de array como parámetro


// el retorno del array de un método

class Test
class Test

{
{

// Método principal
// Método principal

public static void main(String args[])


public static void main(String args[])

{
{

int arr[] = {3, 1, 2, 5, 4};


int arr[] = m1();

// pasar array al método sum


for (int i = 0; i < arr.length; i++)

sum(arr); System.out.print(arr+" ");

}
}

public static void sum(int[] arr)


public static int[] m1()

{
{

// obtener suma de valores del array


// retornando array

int sum = 0;
return new int[]{1,2,3};

for (int i = 0; i < arr.length; i++)


}
sum+=arr;


Salida:
System.out.println("Suma de valores del array: " + sum);

1 2 3
}

Salida: 3.3. Objectos Class para arrays


Suma de valores del array: 15 Cada array tiene un objeto Class asociado, compartido con todos los demás arrays con el mismo tipo de
componente.

3.2. Retornando arrays de métodos Ejemplo:

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:

// Programa Java para demostrar


// Asignar manualmente diferentes tamaños a arrays de dimensión dos

// Objetos de clase para arrays



class DemoArrayIrregular

class Test
{

{
public static void main(String args[])

public static void main(String args[])


{

{
int cursos[][]=new int[];

int intArray[] = new int;


cursos = new int;

byte byteArray[] = new byte;


cursos = new int;

short shortsArray[] = new short;


cursos = new int;


cursos = new int;

// array de Strings
cursos = new int;

String[] strArray = new String;


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 (i=5; i<7;i++)

for (j=0;j<2;j++)

Salida: cursos=j+1;

System.out.println("Entre Semana");

class []= new int []

System.out.println("------------");

tabla = new int


for(i=0;i<5;i++) {

tabla = new int

System.out.print("Dia "+(i+1)+"°: ");

tabla = new int for (j = 0; j < 10; j++)

System.out.print(cursos + " ");

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)+"°: ");

for (j=0 ; j<2 ; j++)

System.out.print(cursos + " ");

Observe que la longitud de la segunda dimensión para los primeros cinco índices es 10 y la longitud de la × System.out.println();

segunda dimensión para los dos últimos índices es 2.


}

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

Dia 7°: 1 2 for (i=0; i<10 ; i++)

num1=i;

El uso de matrices multidimensionales irregulares (o desiguales) no se recomienda para la mayoría de las

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();

5. Asignación de referencias en Arrays System.out.print("num2: ");

for (i=0; i<10 ; i++)

System.out.print(num2 + " ");

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.print("num2 después de la asignación: ");

for (i=0; i<10 ; i++)

System.out.print(num2 + " ");

System.out.println();

//ahora opera el array num1 a través de num2

num2=99;

System.out.print("num1 después de cambiar valor a través de num2: ");

for (i=0; i<10 ; i++)

System.out.print(num1 + " ");

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

num2 después de la asignación: 0 1 2 3 4 5 6 7 8 9

num1 después de cambiar valor a través de num2: 0 1 2 99 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

// clonación de matrices multidimensionales

6. Clonación de arrays class Test

public static void main(String args[])

Cuando clona un array dimensional único, como Object[], se realiza una “copia profunda” con el nuevo array que {

contiene copias de los elementos del array original en lugar de referencias.


int intArray[][] = {{1,2,3},{4,5}};

Ejemplo:
int cloneArray[][] = intArray.clone();

// Programa Java para demostrar


// imprimirá false

// clonación de arrays unidimensionales


System.out.println(intArray == cloneArray);

class Test
// se imprimirá true a medida que se crea una copia poco profunda

{
// es decir, sub-arrays son compartidos

public static void main(String args[])


System.out.println(intArray == cloneArray);

{
System.out.println(intArray == cloneArray);

int intArray[] = {1,2,3};


int cloneArray[] = intArray.clone();


}

// imprimirá false a medida que se crea una copia profunda


Salida:
// para un array unidimensional

System.out.println(intArray == cloneArray);

false

true

for (int i = 0; i < cloneArray.length; i++) {

true
System.out.print(cloneArray+" ");

}
}

7. Uso de length en Arrays


Salida: Debido a que los arreglos se implementan como objetos, cada array tiene asociado una variable de instancia de
longitud (length) que contiene la cantidad de elementos que el array puede contener. (En otras
palabras, length contiene el tamaño del array.) Aquí hay un programa que demuestra esta propiedad:
false

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.
{

public static void main(String args[])

Table de Contenido
{

int lista[]= new int ;


1. Qué es for-each
int num[]={1,2,3};
2. Puntos Importantes for-each
int tabla[][]={
3. Ejemplo con for-each
{1,2,3},
4. Limitaciones del ciclo for-each
{4,5},
5. Iteración sobre arrays multidimensionales
{6,7,8,9}

};

System.out.println("Longitud de lista: "+lista.length);

1. Qué es for-each
System.out.println("Longitud de num: " +num.length);

System.out.println("Longitud de tabla: "+tabla.length);


Al trabajar con arrays, es común encontrar situaciones en las que cada elemento de una matriz debe
System.out.println("Longitud de tabla: " +tabla.length);
examinarse, de principio a fin. Por ejemplo, para calcular la suma de los valores contenidos en una matriz, cada
System.out.println("Longitud de tabla: " +tabla.length);
elemento de la matriz debe examinarse.
System.out.println("Longitud de tabla: " +tabla.length);


Con for:
//Usando length para inicializar lista

for (int i=0; i < lista.length; i++)

int nums[]={1,2,3,4,5};

lista=i*i;
int sum=0;

System.out.print("La lista es: ");


for (int i=0; i<nums.length; i++) sum+=nums;
//Ahora usamos length para mostrar lista

Con for-each:
for (int i=0; i < lista.length; i++)

System.out.print(lista+ " ");

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

2. Puntos Importantes for-each


Algunos puntos importantes de for-each:

Comienza con la palabra clave for al igual que un bucle for normal.


En lugar de declarar e inicializar una variable contador del bucle, declara una variable que es del mismo
tipo que del array, seguido de dos puntos y seguido del nombre del array.

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:
{

public static void main(String[] arg)

int[] marks = { 125, 132, 95, 116, 110 };

int highest_marks = maximum(marks);

System.out.println("El puntaje más alto es " + highest_marks);

public static int maximum(int[] numbers)

int maxSoFar = numbers;

ⓘ // bucle for each

for (int num : numbers)

for (tipo variable : array)

if (num > maxSoFar)

declaraciones usando variable;

}
maxSoFar = num;

Es equivalente a: }

return maxSoFar;

for (int i=0; i<arr.length; i++)


}

{
}
tipo variable = arr;

declaraciones usando variable;


Salida:
}

El puntaje más alto es 132

3. Ejemplo con for-each
4. Limitaciones del ciclo for-each
Ejemplo:
El bucle for-each no es apropiado cuando quiere modificar el array:

for (int num : marks)

// solo cambia num, no el elemento del 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.

for (int num : numbers)

if (num == target)

return ???; // no sabe el índice de num

}
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

for (int i=numbers.length-1; i>0; i--)

public static void main(String args[])

System.out.println(numbers);

int sum=0;

}
int nums[][]= new int ;

for-each no puede procesar dos declaraciones de toma de decisiones a la vez.


//dando valores

for (int i=0; i <2 ; i++)

// esto no se puede convertir fácilmente a un bucle for-each

for (int j=0; j<3; j++)

for (int i=0; i<numbers.length; i++)

nums=(i+1)*(j+1);

if (numbers == arr)

//uso de for-each para mostrar la suma total

{ ...

for (int x[]:nums){

for (int y:x){

}
System.out.println("Valor de: "+y);

sum+=y;

5. Iteración sobre arrays multidimensionales }

System.out.println("Suma total: "+sum);

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

Arrays con ejemplos Valor de: 1

Valor de: 2

IR AL ARTÍCULO Valor de: 3

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

String str1=new String("En Java, los String son objetos");

String str2=new String("Se construyen de varias maneras");

Table de Contenido
String str3=new String(str2);

1. Construyendo String

2. Operando con Métodos de la clase String System.out.println(str1);

3. Ejemplo de todos los métodos de String System.out.println(str2);

4. Arrays de Strings System.out.println(str3);

5. Los String son inmutables

6. String en Argumentos de Línea de Comandos }

1. Construyendo String La salida del programa se muestra a continuación:

En Java, los String son objetos

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

Se construyen de varias maneras

String str = new String("Hola");


2. Operando con Métodos de la clase String
Esto crea un objeto String llamado str que contiene la cadena de caracteres “Hola”. También puedes construir
una String desde otro String. Por ejemplo:
La clase String contiene varios métodos que operan en cadenas. Aquí se detallan todos los métodos:

String str = new String("Hola");


int length(): Devuelve la cantidad de caracteres del String.
String str2 = new String(str);
"Javadesdecero.es".length(); // retorna 16
Después de que esta secuencia se ejecuta, str2 también contendrá la cadena de caracteres “Hola”. Otra forma
fácil de crear una cadena se muestra aquí: Char charAt(int i): Devuelve el carácter en el índice i.

System.out.println("Javadesdecero.es".charAt(3)); // retorna 'a'


String str = "Estoy aprendiendo sobre String en JavadesdeCero.";

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.

"Javadesdecero.es".substring(4,9); // retorna desde


String concat( String str): Concatena la cadena especificada al final de esta cadena.
Nota: En este caso, no considerará el case de una letra (ignorará si está en mayúscula o minúscula).  ×
String s1 = "Java";

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("Cero"); // retorna 11 String palabra1 = "HoLa";

String palabra2 = palabra1.toUpperCase(); // retorna "HOLA"


int indexOf (String s, int i): Devuelve el índice dentro de la cadena de la primera aparición de la cadena
especificada, comenzando en el índice especificado. String trim(): Devuelve la copia de la cadena, eliminando espacios en blanco en ambos extremos. No
afecta los espacios en blanco en el medio.
String s = "Java desde Cero";

int salida = s.indexOf('a',3); //retorna 3 String palabra1 = " Java desde Cero ";

String palabra2 = palabra1.trim(); // retorna "Java desde Cero"


Int lastIndexOf (int ch): Devuelve el índice dentro de la cadena de la última aparición de la cadena
especificada. String replace (char oldChar, char newChar): Devuelve una nueva cadena al reemplazar todas las
ocurrencias de oldChar con newChar.
String s = "Java desde Cero";

int salida = s.lastIndexOf('a'); // retorna 3 String palabra1 = "yavadesdecero";

String palabra2 = palabra1.replace('y' ,'j'); //retorna javadesdecero


boolean equals (Objeto otroObjeto): Compara este String con el objeto especificado.

Boolean salida = "Java".equals("Java"); // retorna true


Nota: s1 sigue siendo yavadesdecero y s2, javadesdecero  ×
Boolean salida = "Java".equals("java"); // retorna false

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

Boolean salida = "Java".equalsIgnoreCase("java"); // retorna true

int compareTo (String otroString): Compara dos cadenas lexicográficamente.

int salida = s1.compareTo(s2); // donde s1 y s2 son

// strings que se comparan

Esto devuelve la diferencia s1-s2. Si :

salida < 0 // s1 es menor que s2

salida = 0 // s1 y s2 son iguales

salida > 0 // s1 es mayor que s2

int compareToIgnoreCase (String otroString): Compara dos cadenas lexicográficamente, ignorando las
consideraciones case.

int salida = s1.compareToIgnoreCase(s2); // donde s1 y s2 son

// strings que se comparan

Esto devuelve la diferencia s1-s2. Si :

salida < 0 // s1 es menor que s2

salida = 0 // s1 y s2 son iguales

salida > 0 // s1 es mayor que s2

String palabra1 = "JavadesdeCero";

// Código Java para ilustrar diferentes constructores y métodos

System.out.println("Cambiando a minúsculas: " +

// de la clase String.

palabra1.toLowerCase());

class DemoMetodosString

// Conversión de cases

String palabra2 = "JavadesdeCero";

public static void main (String[] args)

System.out.println("Cambiando a MAYÚSCULAS: " +

palabra1.toUpperCase());

String s= "JavadesdeCero";

// o String s= new String ("JavadesdeCero");

// Recortando la palabra

String word4 = " JavadesdeCero ";

// Devuelve la cantidad de caracteres en la Cadena.

System.out.println("Recortando la palabra: " + word4.trim());

System.out.println("String length = " + s.length());

// Reemplazar caracteres

// Devuelve el carácter en el índice i.

String str1 = "YavadesdeCero";

System.out.println("Character at 3rd position = "

System.out.println("String Original: " + str1);

+ s.charAt(3));

String str2 = "YavadesdeCero".replace('Y' ,'J') ;

System.out.println("Reemplazando Y por J -> " + str2);

// Devuelve la subcadena del carácter índice i-ésimo

// al final de la cadena

System.out.println("Substring " + s.substring(3));

// Devuelve la subcadena del índice i a j-1.

Salida:
System.out.println("Substring = " + s.substring(2,5));

// Concatena string2 hasta el final de string1.


String length = 13

String s1 = "Java";
Character at 3rd position = a

String s2 = "desdeCero";
Substring adesdeCero

System.out.println("String concatenado = " +


Substring = vad

s1.concat(s2));
String concatenado = JavadesdeCero

Índice de Cero: 11

// Devuelve el índice dentro de la cadena de


Índice de a = 3

// la primera aparición de la cadena especificada.


Comprobando la igualdad: false

String s4 = "Java desde Cero";


Comprobando la igualdad: true

System.out.println("Índice de Cero: " +


Comprobando la igualdad: false

s4.indexOf("Cero"));
Si s1 = s2: false

Cambiando a minúsculas: javadesdecero

// Devuelve el índice dentro de la cadena de


Cambiando a MAYÚSCULAS: JAVADESDECERO

// la primera aparición de la cadena especificada,


Recortando la palabra: JavadesdeCero

// comenzando en el índice especificado.


String Original: YavadesdeCero

System.out.println("Índice de a = " +
Reemplazando Y por J -> JavadesdeCero
s4.indexOf('a',3));

// Comprobando la igualdad de cadenas


4. Arrays de Strings
Boolean out = "Java".equals("java");

System.out.println("Comprobando la igualdad: " + out);

Al igual que cualquier otro tipo de datos, los String se pueden ensamblar en arrays. Por ejemplo:
out = "Java".equals("Java");

System.out.println("Comprobando la igualdad: " + out);

out = "Java".equalsIgnoreCase("jaVA ");

System.out.println("Comprobando la igualdad: " + out);

int out1 = s1.compareTo(s2);

System.out.println("Si s1 = s2: " + out);

// Conversión de cases

// Demostrando arrays de String


// uso de substring()

class StringArray

{
class SubString

public static void main (String[] args)


{

{
public static void main (String[] args)

String str[]={"Java", "desde","Cero"};


{


String str="Java desde Cero";

System.out.println("Array Original: ");


for (String s : str)


//Construyendo un substring

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: ");

for (String s : str)


Salida:
System.out.print(s+ "");

System.out.println("\n");

}
str: Java desde Cero

} substr: 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. {

System.out.println("Aquí se muestran "+ args.length + " argumentos de línea de comando.")


Para comprender completamente por qué las cadenas inmutables no son un obstáculo, utilizaremos otro de los

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);

utilizar se muestra aquí: }

String substring(int beginIndex, int endIndex)

Si DemoLC se ejecuta de esta manera,


Aquí, beginIndex especifica el índice inicial, y endIndex especifica el punto de detención. Aquí hay un programa
que demuestra el uso de substring( ) y el principio de cadenas inmutables:

java DemoLC uno dos tres class Telefono

verá la siguiente salida: public static void main (String[] args)

String numeros[][]={

Aquí se muestran 3 argumentos de línea de comando.


{ "Alex", "123-456"},

Estos son:
{ "Juan", "145-478"},

arg: uno
{ "Javier", "789-457"},

arg: dos
{ "Maria", "784-554"}

arg: tres
};

int i;

if (args.length != 1)

System.out.println("Ejecute así: java Telefono <nombre>");

else {

for (i = 0; i < numeros.length; i++) {

System.out.println(numeros + ": " + numeros);

break;

if (i == numeros.length)

System.out.println("Nombre no encontrado.");

Aquí hay una muestra de ejecución:


String en Argumentos de Línea de Comandos
java Telefono Alex

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

1. Todos los Modificadores de Acceso



Como su nombre indica, los modificadores de acceso en Java ayudan a restringir el alcance de una clase,
En su soporte para la encapsulación, la clase proporciona dos beneficios principales. Primero, vincula datos con el constructor, variable, método o miembro de datos. Hay cuatro tipos de modificadores de acceso disponibles en
código que lo manipula. Usted ha estado aprovechando anteriormente este aspecto de la clase. En segundo lugar, Java:
proporciona los medios por los que se puede controlar el acceso a los miembros. Es esta característica la que se
examina aquí.
1. Default – No se requiere palabra clave

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.

// Programa Java para ilustrar el modificador default


// Programa Java para ilustrar el error

package p1;
// al usar la clase desde un mismo paquete


// con modificador private

// La clase DemoDefault tiene modificador de acceso default


package p1;

class DemoDefault {

void mostrar()
class A {

{
private void mostrar() {

System.out.println("Hola Mundo!");
System.out.println("Java desde Cero");

}
}

}
}

class B{

public static void main(String[] args) {

// Programa Java para ilustrar el error


A obj= new A();

// al usar la clase de un paquete diferente con


//tratando de acceder al método privado de otra clase

// modificador default
obj.mostrar();

package p2;
}

import p1.*;


}
// Esta clase tiene un modificador de acceso predeterminado

public class DemoDefaultEjecutar {

Salida:
public static void main(String args[])

//accessing class Geek from package p1


Error:(15, 12) java: mostrar() has private access in p1.A
DemoDefault obj = new DemoDefault();

obj.mostrar();

}
4. Modificador de acceso protegido (protected)
}

El modificador de acceso protegido se especifica con la palabra clave .


Salida:
Los métodos o miembros de datos declarados como son accesibles dentro del mismo paquete o sub-clases
Error:(12, 9) java: cannot find symbol
en paquetes diferentes.
symbol: class DemoDefault
En este ejemplo, crearemos dos paquetes p1 y p2. La clase A en p1 es public, para acceder a ella desde p2. El
location: class p2.DemoDefaultEjecutar método que se muestra en la clase A está protegido y la clase B se hereda de la clase A y, a continuación, se
accede a este método protegido creando un objeto de clase B.

3. Modificador de acceso privado (private) // Programa Java para ilustrar

// 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) {

B obj = new B();


static
obj.mostrar();
final
}
abstract
} synchronized
transient
volatile
Salida: native

Java desde Cero 7. Puntos importantes


5. Modificador de acceso público (public) Si otros programadores usan tu clase, intente usar el nivel de acceso más restrictivo que tenga sentido para un
miembro en particular. Use a menos que tenga una buena razón para no hacerlo. También evite los campos
públicos, excepto las constantes.
El modificador de acceso público se especifica con la palabra clave .

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.

// Programa Java para ilustrar

// el modificador public

package p1;

public class A {

public void mostrar(){

System.out.println("Java desde Cero");

// Programa Java para ilustrar

// el modificador protected

package p2;

// importar todas las clases en el paquete p1

import p1.*;

public class B extends A {

public static void main(String[] args) {

A obj = new A();

obj.mostrar();

Salida:

// Programa Java para demostrar el paso de objetos a métodos.

Pasar y devolver objetos a métodos en Java

class Demo {

Intermedio   POO int a, b;

1 Comentario por Alex Walton Demo(int i, int j) {

a = i;

b = j;

// devuelve true si los valores

// para las referencias son los mismos

boolean equalTo(Demo obj) {

ⓘ return (obj.a == a && obj.b == b);

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);

Demo ob2 = 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

por el argumento. System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));

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));

llamada por referencia. }

Los cambios en el objeto dentro del método se reflejan en el objeto utilizado como argumento.
}

Table de Contenido Salida:


1. Pasar objetos a métodos
1.1. Explicación con imágenes
ob1 == ob2: true

2. Definir un constructor que toma un objeto de su clase como un parámetro


ob1 == ob3: false
3. Devolución de objetos

1.1. Explicación con imágenes


1. Pasar objetos a métodos
Se crean tres objetos ‘ob1’, ‘ob2’ y ‘ob3’:

En Java podemos pasar objetos a métodos. Por ejemplo, considere el siguiente programa: Demo ob1 = new Demo(100, 22);

Demo ob2 = new Demo(100, 22);

Demo ob3 = new Demo(-1, -1);

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.

System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));

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.

if(obj.a == a && obj.b == b)

De nuevo ‘obj’ se reasignará a ‘ob3’ a medida que se ejecuta la siguiente instrucción.

System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));

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.

// Programa Java para utilizar un objeto para inicializar otro

class Caja {

double ancho, alto, largo;

//Observe este constructor.

//Toma un objeto de tipo Caja.

//Este constructor usa un objeto para inicializar otro.



Volumen de mi Caja es 3000.0

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.

Caja (double w, double h, double d)


// Programa Java para demostrar la devolución de objetos

ancho = w;
class DemoRetornarObjeto {

alto = h; int a;

largo = d;

}
DemoRetornarObjeto(int i)

double volumen()
a = i;

{
}

return ancho * alto * largo;


}
// Este método devuelve un objeto

}
DemoRetornarObjeto incrByTen(){

public class Test {


DemoRetornarObjeto temp = new DemoRetornarObjeto(a+10);

public static void main(String args[]) {


return temp;

Caja miCaja = new Caja(10, 20, 15);


}

// creando una copia de miCaja


public class Test {

Caja miclon = new Caja(miCaja);


public static void main(String args[]) {


DemoRetornarObjeto ob1 = new DemoRetornarObjeto(2);

double vol;
DemoRetornarObjeto ob2;

// obtener volumen de miCaja


ob2 = ob1.incrByTen();

vol = miCaja.volumen();

System.out.println("Volumen de mi Caja es " + vol);


System.out.println("ob1.a: " + ob1.a);


System.out.println("ob2.a: " + ob2.a);

// obtener volumen de miclon


}

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.

Si no se lanza una excepción, entonces un bloque try finaliza normalmente, y todas sus ×


declaraciones catch se pasan por alto. La ejecución se reanuda con la primera instrucción después del
último catch. Por lo tanto, las declaraciones catch se ejecutan solo si se lanza una excepción.

3.1. Un ejemplo de excepción simple



Hay dos subclases directas de Throwable: Exception y Error: Aquí hay un ejemplo simple que ilustra cómo observar y atrapar una excepción. Como saben, es un error intentar
indexar una matriz más allá de sus límites. Cuando esto ocurre, la JVM lanza
una ArrayIndexOutOfBoundsException. El siguiente programa genera a propósito tal excepción y luego la
1. Las excepciones de tipo Error están relacionadas con errores que ocurren en la Máquina Virtual de Java y no
atrapa:
en tu programa. Este tipo de excepciones escapan a su control y, por lo general, tu programa no se ocupará de
ellas. Por lo tanto, este tipo de excepciones no se describen aquí.
public class ExcDemo {

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;

usa para representar varios tipos comunes de errores en tiempo de ejecución.

try {

System.out.println("Antes de que se genere la excepción.");

3. Fundamentos de manejo de excepciones //generar una excepción de índice fuera de límites

nums=10;

}catch (ArrayIndexOutOfBoundsException exc){

El manejo de excepciones Java se gestiona a través de cinco palabras clave: try, catch, throw, throws,



de este //Capturando la excepción

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. }

System.out.println("Después de que se genere la excepción.");

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.

Índice fuera de los límites!

3. Uso de try y catch Después 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.
}

catch (TipoExcepcion2 exOb){


Recuerde, si no se lanza una excepción por un bloque try, no se ejecutarán declaraciones catch y el control del
//Manejador para TipoExepción2
programa se reanudará después de la instrucción catch. Para confirmar esto, en el programa anterior, cambie la
} línea

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

// en las declaraciones catch

public class ExcDemo {

// Una excepción puede ser generada por un método


public static void main(String[] args) {

// y atrapada por otro


public class ExcEjemplo {


//Aquí, num es más grande que denom

//Generando una exepción


int nums[]={4,8,16,32,64,128,256,512};

static void genExcepcion(){


int denom[]={2,0,4,4,0,8};

int nums[]= new int;



for (int i=0;i< nums.length;i++){

System.out.println("Antes de que se genere la excepción.");


try {

System.out.println(nums+" / "+

//generar una excepción de índice fuera de límites


denom+" es "+nums/denom);;

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.");

} }

catch (Throwable exc){

//Capturando la excepción (superclase)

public class ExcDemo {

System.out.println("Alguna excepción ocurrió.");

public static void main(String[] args) {

int nums[]=new int;

try {

}
ExcEjemplo.genExcepcion();

}catch (ArrayIndexOutOfBoundsException exc){

//Capturando la excepción
Salida:
System.out.println("Índice fuera de los límites!");

}
4 / 2 es 2

System.out.println("Después de que se genere la excepción.");


Alguna excepción ocurrió.

}
16 / 4 es 4

} 32 / 4 es 8

Alguna excepción ocurrió.

Salida: 128 / 8 es 16

No se encontró ningún elemento.

No se encontró ningún elemento.


Antes de que se genere la excepción.

Índice fuera de los límites!

En este caso, catch (Throwable) detecta todas las excepciones excepto ArrayIndexOutOfBoundsException. El


Después de que se genere la excepción.
problema de detectar excepciones de subclase se vuelve más importante cuando crea excepciones propias.

Como se llama a genExcepcion() desde un bloque try, la excepción que genera es capturada por catch en main().


Entender, sin embargo, que si genExcepcion() había atrapado la excepción en sí misma, nunca se hubiera pasado
a main().
4. Los bloques try pueden ser anidados
3.3. Captura de excepciones de subclase Un bloque try se puede anidar dentro de otro. Una excepción generada dentro del bloque try interno que no está
atrapada por un catch asociado con este try, se propaga al bloque try externo. Por ejemplo, aquí la
ArrayIndexOutOfBoundsException no es capturada por el catch interno, sino por el catch externo:

// Uso de un bloque try anidado


throw excepcOb;
public class TryAnidado{

public static void main(String[] args) {


Aquí, excepcOb debe ser un objeto de una clase de excepción derivada de Throwable. Aquí hay un ejemplo que
//Aquí, num es más grande que denom
ilustra la instrucción arrojando manualmente una ArithmeticException:
int nums[]={4,8,16,32,64,128,256,512};

int denom[]={2,0,4,4,0,8};

//Lanzar manualmente una excepción

public class ThrowDemo {

try { //try externo

public static void main(String[] args) {

for (int i = 0; i < nums.length; i++) {

try{

try { //try anidado

System.out.println("Antes de lanzar excepción.");

System.out.println(nums + " / " +

throw new ArithmeticException(); //Lanzar una excepción

denom + " es " + nums / denom);

}catch (ArithmeticException exc){

} catch (ArithmeticException exc) {

//Capturando la excepción

//Capturando la excepción

System.out.println("Excepción capturada.");

System.out.println("No se puede dividir por cero!");

}
System.out.println("Después del bloque try/catch");

catch (ArrayIndexOutOfBoundsException exc) {

//Capturando la excepción

System.out.println("Alguna excepción ocurrió.");

Salida:
System.out.println("ERROR: Programa terminado.");

} Antes de lanzar excepción.

}
Excepción capturada.

} Después del bloque try/catch

Salida: Observe cómo se creó la ArithmeticException utilizando new en la instrucción throw. Recuerde, throw arroja un


objeto. Por lo tanto, debe crear un objeto para “lanzar“. Es decir, no puedes simplemente lanzar un tipo.
4 / 2 es 2

No se puede dividir por cero!

16 / 4 es 4

6. Re-lanzar una excepción:


32 / 4 es 8

No se puede dividir por cero!


Una excepción capturada por una declaración catch se puede volver a lanzar para que pueda ser capturada por
128 / 8 es 16
un catch externo. La razón más probable para volver a lanzar de esta manera es permitir el acceso de múltiples
Alguna excepción ocurrió.

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.

5. Lanzar una excepción


Los ejemplos anteriores han estado capturando excepciones generadas automáticamente por la JVM. Sin
embargo, es posible lanzar manualmente una excepción utilizando la instrucción throw. Su forma general se
muestra aquí:
Hasta este punto, hemos estado detectando excepciones, pero no hemos estado haciendo nada con el objeto de
//Relanzando un excepción
excepción en sí mismo. Como muestran todos los ejemplos anteriores, una cláusula catch especifica un tipo de
public class Rethrow {
excepción y un parámetro. El parámetro recibe el objeto de excepción. Como todas las excepciones son subclases
public static void genExcepcion() {
de Throwable, todas las excepciones admiten los métodos definidos por Throwable. Varios de uso común se
//Aquí, num es más largo que denom
muestran en la siguiente tabla:
int nums[] = {4, 8, 16, 32, 64, 128, 256, 512};

int denom[] = {2, 0, 4, 4, 0, 8};


Tabla de métodos Throwable.

Método Sintaxis Descripción
for (int i = 0; i < nums.length; i++) {

try { getMessage String getMessage() Devuelve una descripción de la excepción.


System.out.println(nums + " / " +

denom + " es " + nums / denom);


String
getLocalizedMessage Devuelve una descripción localizada de la excepción.
getLocalizedMessage()
} catch (ArithmeticException exc){

//Capturando la excepción

Devuelve un objeto String que contiene una


System.out.println("No se puede dividir por cero!.");
descripción completa de la excepción. Este método lo
}
toString String toString()
llama println() cuando se imprime un objeto
catch (ArrayIndexOutOfBoundsException exc) {
Throwable.
//Capturando la excepción

System.out.println("No se encontró ningún elemento.");


printStackTrace() void printStackTrace() Muestra el flujo de error estándar.
throw exc; //Relanzando la excepción

void
}

printStackTrace printStackTrace(PrintStream Envía la traza de errores a la secuencia especificada.


}
s)
}

} void
printStackTrace printStackTrace(PrintWriter Envía la traza de errores a la secuencia especificada.
s)
public class RethrowDemo {

public static void main(String[] args) {


Devuelve un objeto Throwable que contiene un
try{
fillInStackTrace Throwable fillInStackTrace() seguimiento de pila completo. Este objeto se puede
volver a lanzar.
Rethrow.genExcepcion();

catch (ArrayIndexOutOfBoundsException exc){


De los métodos definidos por Throwable, dos de los más interesantes son printStackTrace() y toString().
//Recapturando la excepción

System.out.println("ERROR - Programa terminado");


Puede visualizar el mensaje de error estándar más un registro de las llamadas a métodos que conducen a la
}
excepción llamando a printStackTrace().
}
Puede usar toString() para recuperar el mensaje de error estándar. El método toString() también se invoca
} cuando se usa una excepción como argumento para println().
El siguiente programa demuestra estos métodos:
Salida:

4 / 2 es 2

No se puede dividir por cero!.

16 / 4 es 4

32 / 4 es 8

No se puede dividir por cero!.

128 / 8 es 16

No se encontró ningún elemento.

ERROR - Programa terminado

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().

7. Una mirada más cercana a Throwable

public class ExcDemo {


try{

static void genExcepcion(){


//bloque de código para monitorear errores

int nums[]=new int;


}


catch(TipoExcepcion1 exOb){

System.out.println("Antes de lanzar excepción.");


//manejador para TipoExcepcion1

nums=10;
catch(TipoExcepcion2 exOb){

System.out.println("Esto no se mostrará.");
//manejador para TipoExcepcion2

}
}

}
//...


finally{

class MetodosThrowable{
//código final

public static void main(String[] args) {


}
try{

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);

System.out.println("\nTraza de errores: ");


Aquí hay un ejemplo de finally:
exc.printStackTrace();

}
//Uso de finally

System.out.println("Después del bloque catch.");


public class UsoFinally {

}
public static void genExcepecion(int rec) {

}
int t;

int nums[]=new int;

Salida:

System.out.println("Recibiendo "+rec);

try {

Antes de lanzar excepción.

switch (rec){

Mensaje estándar:

case 0:

java.lang.ArrayIndexOutOfBoundsException: 7

t=10 /rec;

break;

Traza de errores:

case 1:

java.lang.ArrayIndexOutOfBoundsException: 7

nums=4; //Genera un error de indexación

at ExcDemo.genExcepcion(ExcDemo.java:8)

break;

at MetodosThrowable.main(ExcDemo.java:16)

case 2:

Después del bloque catch.


return; //Retorna desde el blorec try

8. Uso de finally }

catch (ArithmeticException exc){

//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. }

catch (ArrayIndexOutOfBoundsException exc){

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)

public static void main(String[] args) {


throws java.io.IOException {

for (int i=0;i<3;i++){


System.out.println(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,

// una llamada debe incluirse dentro de un bloque try

ch = prompt("Ingresar una letra");

9. Uso de throws } catch (java.io.IOException exc) {

System.out.println("Ocurrió una excepción de E/S");

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);

tipo-retorno nombreMetodo(lista-param) throws lista-excepc {


}
// Cuerpo

} 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.

Aquí se explica cómo puede usar la función multi-catch para


Para qué sirve la palabra clave (keyword) super en Java? La palabra clave “super” entró en escena con el
capturar ArithmeticException y ArrayIndexOutOfBoundsException con una única cláusula catch:
concepto de Herencia y esto es lo que necesitas saber!

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

2. Uso de super con métodos


class MultiCatch {

3. Uso de super con constructores


public static void main(String[] args) {

int a=28, b=0;


4. Otros puntos importantes de ‘super’
int resultado;

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

chars ='X'; //genera un ArrayIndexOutOfBoundsException

Ejemplo:
}catch (ArithmeticException | ArrayIndexOutOfBoundsException e){

System.out.println("Excepción capturada: "+e);

}
/* clase base vehicle */

}
class Vehicle

System.out.println("Después del multi-catch");


{

}
int maxSpeed = 120;

} }

Salida:
/* subclase Car extendiendo de vehicle */

class Car extends Vehicle

Excepción capturada: java.lang.ArithmeticException: / by zero


{

Excepción capturada: java.lang.ArrayIndexOutOfBoundsException: 5

int maxSpeed = 180;

Después del multi-catch


void display()

El programa generará una ArithmeticException cuando se intenta la división por cero. Generará {

una ArrayIndexOutOfBoundsException cuando se intente acceder fuera de los límites de chars. Ambas


/* imprime maxSpeed de la clase base (vehicle) */

excepciones son capturadas por la declaración única de catch.


System.out.println("Velocidad máxima: " + super.maxSpeed);

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 {

como final, pero esto no es necesario. public static void main(String[] args)

Car small = new Car();

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.

2. Uso de super con métodos


Esto se usa cuando queremos llamar al método de clase padre. Entonces, cuando una clase padre e hijo tienen
los mismos métodos nombrados, entonces para resolver la ambigüedad utilizamos la palabra clave super. Este
fragmento de código ayuda a comprender el uso dicho de 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.
}

3. Uso de super con constructores


/* Subclase Student */

class Student extends Person

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:
{

System.out.println("Esta es una clase estudiante");


Ejemplo:
}

// Tenga en cuenta que display() solo está en la clase Student


/* superclase Person */

class Person

void display()

{
{

Person()

// invocará o llamará al método message() de la clase actual

message();
{

System.out.println("Constructor de la clase Person");

// invocará o llamará al método message() de la clase padre


}

super.message();
}
}

} /* subclase Student extiende de la clase Person */

class Student extends Person

/* Programa Controlador Test */

class Test
Student()

public static void main(String args[])


// invoca o llama al constructor de la clase padre

{
super();

Student s = new Student();


System.out.println("Constructor de la clase Student");

// llamando a display() de Student

s.display();
}

/* Programa Controlador Test */

class Test
Overriding en Java (Anulación de métodos)
{

POO
public static void main(String[] args)

Student s = new Student();


2 Comentarios por Alex Walton
}

Salida:

Constructor de la clase Person


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.

4. Otros puntos importantes de ‘super’ Table de Contenido


1. Qué es Overriding en Java
2. Ejemplo de anulación de Método
La llamada a super() debe ser la primera instrucción en el constructor de la clase derivada (Student en el 3. Anulación de métodos soportan polimorfismo
ejemplo).
4. ¿Por qué anular los métodos?
Si un constructor no invoca explícitamente un constructor de superclase, el compilador de Java inserta
automáticamente una llamada al constructor sin argumento de la superclase. Si la superclase no tiene un
constructor sin argumentos, obtendrá un error en tiempo de compilación. Por ejemplo, el objeto hace tener
un constructor, por lo que si objeto es la única superclase, no hay ningún problema.
Si un constructor de una subclase invoca un constructor de su superclase, ya sea explícita o
1. Qué es Overriding en Java
implícitamente, puede pensar que se llamó a toda una cadena de constructores, todo el camino de
regreso al constructor de Object. Esto, de hecho, es el caso. Se llama encadenamiento de En cualquier lenguaje de programación orientado a objetos, Anulación o Overriding es una característica que
constructores. permite que una subclase o clase secundaria proporcione una implementación específica de un método que ya
está provisto por una de sus superclases o clases principales. Cuando un método en una subclase tiene el mismo
nombre, los mismos parámetros o firma y el mismo tipo de devolución (o subtipo) que un método en su superclase,
se dice que el método de la subclase anula el método en la superclase.

Qué es Overriding en Java


La anulación de método es una de las formas en que Java logra el polimorfismo de tiempo de ejecución. La
versión de un método que se ejecuta estará determinada por el objeto que se utiliza para invocarla. Si se utiliza un
objeto de una clase padre para invocar el método, entonces se ejecutará la versión en la clase padre, pero si se
utiliza un objeto de la subclase para invocar el método, entonces se ejecutará la versión en la clase hija.

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

Cuando se invoca mostrar() en un objeto de tipo B, se utiliza la versión mostrar() definida en B. Es decir, la


Cuando se llama a un método anulado dentro de una subclase, siempre se referirá a la versión de ese método
versión mostrar() dentro de B anula la versión declarada en A. Si desea acceder a la versión de la superclase de un
definida por la subclase. La versión del método definida por la superclase estará oculta. Considera lo siguiente:
método ‘anulado’, puede hacerlo utilizando super.

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.

A(int a,int b){


class B extends A {

i=a;
int k;

j=b;

}
B(int a, int b, int c){


super(a,b);

//Mostrar i, j
k=c;

void mostrar(){
}

System.out.println("i, j: "+i+", "+j);


}
//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;

B(int a, int b, int c){

class Override{

super(a,b);

public static void main(String[] args) {

k=c;

B b=new B(1,2,3);

b.mostrar(); //Esto llama a mostrar() en B

//mostrar k - esto oculta el método mostrar() en A

void mostrar(){

}
System.out.println("k: "+k);

}
Salida:

class Override{
i, j: 1, 2

public static void main(String[] args) {


k: 3
B b=new B(1,2,3);

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(){

referencia de superclase, se ejecutan diferentes versiones del método.


System.out.println("i, j: "+i+", "+j);

} //Demostración de Polimorfismo

class Sup{

void desde(){
class B extends A {
System.out.println("desde() Sup");

int k;

B(int a, int b, int c){


super(a,b);
class Sub1 extends Sup{

k=c;
void desde(){
}

System.out.println("desde() Sub1");

//sobrecarga de mostrar()

void mostrar(String msg){


System.out.println(msg+k);

class Sub2 extends Sup{

}
void desde(){
}
System.out.println("desde() Sub2");

class Override{
}

public static void main(String[] args) {

B b=new B(1,2,3);
class Polimorfismo {

b.mostrar("Esto es k: "); //Esto llama a mostrar() en B


public static void main(String[] args) {

b.mostrar(); //Esto llama a mostrar() en A


Sup superob=new Sup();

}
Sub1 subob1=new Sub1();

} Sub2 subob2=new Sub2();

Salida: Sup referencia;

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;

3. Anulación de métodos soportan polimorfismo referencia.desde();

}
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.

4. ¿Por qué anular los métodos? ⓘ

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

1. Variables con Palabra Clave final


Cuando una variable se declara con la palabra clave final, su valor no se puede modificar, esencialmente, es una
constante. Esto también significa que debe inicializar una variable final.

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:

final int LIMITE=5;

final int LIMITE;


static final double PI = 3.141592653589793;

1.1. Inicializar una variable final


Debemos inicializar una variable final, de lo contrario el compilador emitirá un error en tiempo de compilación. Una
variable final solo se puede inicializar una vez, ya sea a través de un inicializador o una declaración de asignación.
Hay tres formas de inicializar una variable final:

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

// de inicializar una variable final

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

generará un error de tiempo de compilación. {

// una variable final

3. Una variable estática final en blanco se puede inicializar dentro de un bloque estático.
// inicialización directa

final int LIMITE = 5;

Veamos diferentes formas de inicializar una variable final a través de un ejemplo.


// una variable final en blanco

final int CAPACIDAD;

// otra variable final en blanco

final int MINIMO;

// una variable static final PI

// inicialización directa

static final double PI = 3.141592653589793;

// una variable static final en blanco

static final double CONSTANTEEULER;

ⓘ // bloque inicializador de instancias

// para inicializar CAPACIDAD

CAPACIDAD = 25;

// bloque inicializador static

// para inicializar CONSTANTEEULER

static{

CONSTANTEEULER = 2.3;

// consctructor para inicializar MINIMO

// Tenga en cuenta que si hay más de un constructor,

// debe inicializar MINIMO en ellos también

public JDC()
{

MINIMO = -1;

1.2. Cuándo usar una variable final


La única diferencia entre una variable normal y una variable final es que podemos reasignar el valor a una variable
normal, pero no podemos cambiar el valor de una variable final una vez asignada. Por lo tanto, las variables
finales deben usarse solo para los valores que queremos que permanezcan constantes durante la ejecución
del programa.

1.3. Variable final de referencia


Cuando una variable final es una referencia a un objeto, esta variable final se denomina variable final de
referencia. Por ejemplo, una variable final de StringBuffer se parece a:
final StringBuffer cadena; //Programa Java para demostrar

//una variable local final

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

objeto, consulte el siguiente ejemplo: final int i;

i=20;

//Programa Java para demostrar


System.out.println(i);

// la variable final de referencia


}

class JDC {
}

public static void main(String[] args) {

//una variable final de referencia


Salida:
final StringBuilder cadena=new StringBuilder("Java");

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

} //final con for-each

class JDC {

Salida: public static void main(String[] args) {

int arr[]={1,2,3};

//final con sentencia for-each

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

//Programa Java para demostrar

//que la reasignación de la variable final


Explicación: Dado que la variable i está fuera del alcance de cada iteración del bucle, en realidad se vuelve a ×
//lanzará un error en tiempo de compilación
declarar cada iteración, lo que permite utilizar el mismo símbolo (es decir, i) para representar múltiples
class JDC {
variables.
static final int CAPACIDAD=4;

public static void main(String[] args) {


2. Clases finales
//reasignando variable final

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.

Compiler Error: cannot assign a value to final variable CAPACIDAD

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

// La siguiente clase es ilegal.

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

final void m1()

System.out.println("Este es un método final.");

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.

También podría gustarte