sun certified java programmer (scjp) carlos oñate bravo sun certified java programmer (scjp)...
TRANSCRIPT
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Sun Certified Java Programmer (SCJP)
Capítulo 3: Asignaciones
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Stack - Heap(Vista Rápida)
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Stack – Heap
• Para la mayor partes de las piezas de los programas en Java residen en una de dos partes de la memoria: Stack o Heap.
• Fijación en variables de instancia, variables locales y objetos.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Ejemplo:class Collar{}1. public class Perro {2. Collar c;3. private String nombre;4. public static void main(){5. Perro perro;6. perro = new Perro();7. perro.setNombre("Bobby");8. }9. public void andar(Perro p){10. c = new Collar();11. p.setNombre("bobby");12. }13. public void setNombre(String nombrePerro) {14. this.nombre = nombrePerro;15. }16.}
Stack – Heap
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Lo que sucede:
Linea 4 - main() va al stack.Linea 5 - perro es puesto en el stack.Linea 7 - andar() y p son puestos en el stack.Linea 10 - Objeto collar es creado en el heap y asignado a la variable de instancia c.Linea 11 - setNombre() y el parámetro nombrePerro son puestos en el stack.
“bobby” es creada en el pool de strings.Linea 14 - variable de instancia nombre es ubicada en el heap con referencia hacia “bobby”Luego de esto se empiezan a liberar los métodos y variables que están en el stack.Empezando con la ultima agregada, en esta caso el método setNombre y la variable nombrePerro.
Stack – Heap
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Saber desarrollar código que declare, inicialice, y usos de primitivos, arreglos, enums y objetos como estáticos, instancias y variables locales.También saber usar código correcto que aplique correctamente el operador apropiado incluyendo =,+=,-=
Literales, Asignaciones y Variables (Objetivos del examen)
Valores Literales para todos los tipos primitivos
Un literal primitivo es simplemente una representación de código fuente de un tipo de dato primitivo.
Eje:‘b’ //literal char42 // literal intfalse // literal boolean254.125 // literal double
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Integer
Hay 3 maneras de representarlos: decimal (base 10),octal (base 8) y hexadecimal (base 16).
Literal Decimal
Común y corriente, no necesita nada especial para representarlo en java.
Literal Octal
Va del 0 al 7. Se lo representa poniendo un cero en frente del numero:Eje:
int siete = 07;int ocho = 010;int nueve = 011;
Notar que solo pueden ser dígitos del 0 al 7, y se pueden poner hasta 21 dígitos sin contar el cero de en frente.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Integer
Literal Hexadecimal
Se lo representa poniendo el prefijo 0x (cero-x) o el sufijo L. Va del 0 a la f. Se acepta minúsculas o mayúsculas. Se pueden poner hasta 16 dígitos sin incluir el prefijo 0x.
Ej:int x=0x00001;int y=0x7ffff;int z=0xffffffff;System.out.println("x: "+x+" y: "+y+" z: "+z);
long a=0xfffffffffL;System.out.println("a: "+a);
Resp: x: 1 y: 524287 z: -1
Resp: a: 68719476735
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Punto-Flotante
Son definidos como un numero, un símbolo de decimal y mas numero representando la fracción.
Eje:double d = 1234.1587;
Los valores de punto flotante don definidos como double ( 64 bits ) por defecto, así que si se quiere asignar a un tipo float ( 32 bits ), se debe poner el sufijo F o f al numero.
Eje:float f = 2134.124f;Si no se coloca la f o F, dará un error de compilación.
También se puede poner el sufijo D o d a los doble, pero no es necesario.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Boolean
Un boolean puede ser definida solo como true o false.
OJO: No se pueden asignar números en vez de valores boolean. Ni ponerlos en lugares en donde un boolean es requerido.
Eje:boolean b1 = true;
boolean b2 = 1;
int x=1;if ( x ) {}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Caracteres
Es representado por un caracter entre comillas simples. Tambien se lo puede escribir en el valor Unicode del carácter.
Eje:char a = 'a';
char N = '\u004E';
Recordar que un entero es solo un número sin signo de 16 bits. Lo que significa que puede ser un numero de 0 a 65535.
char d = 0x64; char A = 65; char f = (char)70000;
En el último se necesita el cast, puesto que pasa del máximo permitido. Si no daría error de compilación. También se puede asignar un numero negativo, pero con cast.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Literales Caracteres
Valores de Literales String
Se los representa en la forma mas sencilla con comillas dobles.
Eje:String string = “hola”;
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Es el =, en donde el lado derecho es asignado al lado izquierdo.
Antes que nada empecemos con: que es una variable??? Como una variable esta relacionada con su valor???
Entonces una variable es un sostenedor de bits. Se puede tener sostenedores int, double, Button, etc.
Un byte por ejemplo, con valor de 6 es 00000110, representado por 8 bits.Pero no pasa lo mismo con las variables de referencia a Objetos, las cuales son solo eso, variables de referencia.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Variable de Referencia
Las cuales representan bits para llegar al objeto.Cómo es representada la variable, depende de la maquina virtual, pero lo que hay que estar seguro es que no es el objeto.Cuando la variable no ha sido asignada o ha sido asignada explícitamente a null, entonces la variable contendrá el valor null.
Asignadores primitivos
Existen 12 distintos operadores de asignación, pero solo se cubrirán los 5 mas usados (Capitulo 4).Se puede asignar un valor primitivo o el resultado de una expresión.
Eje:int x = 7;int y = x+7;int z = x + y;
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Asignadores primitivos
Algo importante de recordar es que un literal entero como el 7 por ejemplo esta un int implícito.
Si tenemos:byte b = 7;Existe un cast implicito. ==> byte b = (byte) 7;
Pero si tenemos:
byte b = 1;byte c = 2;byte d = b + c;==> Daría Error, puesto que existe la regla de que int-o-mas pequeño, da como resultado un int.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Cast Primitivos
Puede ser implícito o explicito, uno implícito se da cuando se hace widening conversión, que es cuando se pone una cosa pequeña en un contenedor mas grande.
En cambio cuando se va de uno grande a un contenedor mas pequeño, se tiene que aplicar un cast explicito, aceptando la completa responsabilidad del cast.
Explicitofloat f = 100.02f;int i = (int)f; ==> perdida de precisión.int id = (int) 21.324; ==> perdida de precisión. se pierden todos los decimales.
Eje:Implícitoint i = 1;float f = i; double d = 100L;
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Cast Primitivos
También hay que tomar en cuenta el máximo que puede almacenar el contenedor cuando se hace el cast explicito.
Eje: long l = 130L; byte b = (byte)l;
System.out.println("The byte is " + b);
OJO: No da error de compilación ni de ejecución, pero el comportamiento de la asignación de valor no es el que se ve a simple vista. Lo que sucede es que los bits de la izquierda desaparecen y el ultimo bit de la izquierda, se lo toma como signo, si es 1 se hace negativo el numero.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Operador de Asignación
Asignación de Números de Punto Flotante(NPF)
Primero hay que saber que todo NPF implica un numero de 64 bits (double), si se intenta asignar un NPF a un float, el compilador sabe que no se tiene suficiente espacio en un contener float para un double. Así que si se quiere realizar una asignación como esta se puede hacer los siguientes pasos.
float f = (float) 32.2;float f = 32.2f;float f = 32.2F;
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignaciones de un literal que es muy grande para una variable
Lo que se hace es cortar los bits mas significativos, pero tomando en cuenta que el bit del signo.Eje:
•byte b = 128;•Al asignar 128, se indica de que un numero de 32 bits, porque se lo
trata como un int. Siendo asi la representación seria •00000000000000000000000010000000•Para que pase a un byte, se deja solo 8 bits, sabiendo que el mas de
la izquierda representa el signo. Así solo queda•10000000 ==> Negativo•A lo que se le saca el complemento a dos, para secar el número
negativo, lo que nos da•10000000 ==> 128•Entonces nos da•-128
OJO: Así que si se quiere hacer, se lo hace con un cast explicito. Con lo cual se le esta diciendo al compilador que uno sabe lo que se esta haciendo y por qué.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignación de una variable primitiva a otra variable primitiva.
Si se tiene:int a= 6;int b =a;
Entonces lo que se le esta diciendo al compilador es que se le asigne un patrón de bits del numero 6 a la variable a, y luego que se haga una copia del patrón de bits de a y se lo asigne a b.
Así que no se crea ninguna relación entre las dos variables, o sea, si la una cambia, la otra no se ve afectada por el cambio.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignación a una Variable de Referencia
Si se tieneButton b = new Button();Pasan 3 cosas: - Se crea una variable b de tipo Button - Se crea un objeto Button en el heap. - Se asigna el objeto creado Button a la variable de referencia b
En esta asignación que acabamos de ver, se esta creando espacio para la variable de referencia, pero no el objeto Button.A una variable de Referencia se le puede asignar null, lo que significa que no esta apuntando a ningún lado.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignación a una Variable de Referencia
Si tenemos:
public class Animal{ public void caminar(){} public static void main(String[] args){ Animal perroAnimal = new Perro(); Perro perroPerro = new Animal(); }}public class Perro extends Animal{ public void ladrar(){}}
La aignacion de perroAnimal es valida, mientras que la de perroPerro no, porque como aprendimos en el capitulo pasado, la asignaciones de subclases a una variable de referencia es posible, pero no lo contrario.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Alcance de una variable
Cuando se crea una variable la primera pregunta que se viene es cuando dura dicha variable??
class Layout { // class static int s = 343; // variable estatica int x; // variable de instancia { x = 7; int x2 = 5; } // bloque de inicialización Layout() { x += 8; int x3 = 6;} // constructor void doStuff() { // método int y = 0; // variable local for(int z = 0; z < 4; z++) { // codigo de bloque for y += z + x; } }}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Alcance de una variable
Entonces tenemos:s – variable estatica.X – variable de instanciaY – variable localZ – variable de bloqueX2 – variable del bloque init, especie de variable de bloque.X3 – variable del constructor, especie de variable de bloque.
Para propósito de explicación, podemos decir que existen 4 tipos básicos de alcance de variables:
• Variables de bloque, que viven mientras en bloque de código es ejecutado.
• Variables locales son las siguientes, viven tanto como el método que las contiene, permaneces en el stack, y aun estando viva pueden estar fuera de alcance.
• Variables de instancia, son las siguientes en duración, comienzan cuando una instancia de la clase es creada, y muere cuando dicha instancia es acabada.
• Variable estáticas que son las que mas sobreviven, empiezan cuando la clase es cargada, hasta que dure en la JVM
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Alcance de una variable (errores)
Los errores de alcance se pueden presentar de varias formas, la más común es tratar de alcanzar una variable que esta fuera de alcance.
• Tratar de acceder a una instancia de variable no estática, desde un contexto estático.
public class variables { int no_estatica = 0; public static void sumar(){ no_estatica++; } public static void main(String[] args){ no_estatica++; }
}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Alcance de una variable (errores)
• Tratar de acceder a una variable local de un metodoA desde un metodoB. void metodo(){ int y = 0; metodo2(); y++; } void metodo2(){ y++; }
• Tratar de acceder a una variable de bloque después de que el bloque haya terminado. void metodo3(){ for ( int z = 0 ; z < 5 ; z++ ){ boolean es_tres = false; if ( z == 3 ) es_tres = true; } System.out.println(" es_tres : "+ es_tres); }
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando una variable o arreglo de elementos que no esta inicializado o asignado
Son variables definidas a nivel de las clases, son inicializadas con el valor por default.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Variables de instancia Primitivos y Objetos
Java nos da la oportunidad de declara una variable con inicialización o sin inicialización, pero el comportamiento dependerá de la variable, ya sea objetos o primitivos.
Algo importante es que las variables locales también llamadas stack, temporales, o de métodos, tienen el mismo comportamiento que las variables de instancia. Aunque en el compilador no nos permitirá dejar una variable local sin inicializar. Esto nos habla del comportamiento de la inicialización de variables en un ambiente determinado.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Variables de Instancia Primitivas
Son las declaradas en las clases.
Eje:public Cumpleanio{
int anio;void mostrarAnio(){
System.out.println(“Anios: ”+anio);}Public static void main(String[] args){
Cumpleanio c = new Cumpleanio();c.mostrarAnio();
}}
Res: Anios: 0
OJO: Es buena idea inicializar las variables porque así se hace mas fácil y comprensible el mantenimiento, para otras personas.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Instancia de Variables de Referencia de Objetos
La inicicalizacion para variables de referencia es totalmente diferente a la de objetos primitivos.
Eje:public class Libro { private String titulo; public String getTitulo() { return titulo; } public static void main(String args[]){ Libro libro = new Libro(); System.out.println("Libro: "+libro.getTitulo() ); }}
OJO: Aquí no da problema en la compilación, pero hay que recordar que la asignación es null, no “”, que no es lo mismo.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Instancia de Variables de Referencia de Objetos
Pero si tenemos:
public class Libro { private String titulo; public String getTitulo() { return titulo; } public static void main(String args[]){ Libro libro = new Libro(); String titulo = libro.getTitulo(); String minusculas = titulo.toLowerCase(); }}
OJO: Para el examen se tiene que tomar en cuenta el código desde el inicio, ver los valores en las variables y tener en cuénta que el valor de título es una copia de la variable de instancia título, y que si su valor es null, este también lo será.
Dará un error, puesto que se tratara de aplicar un método de conversión a un valor null.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Variables de Instancia de Arreglos
Para empezar un arreglo es un objeto, así que si no ha sido inicializado explícitamente, el valor de inicialización, será null.
Bottom Line: Un arreglo siempre , siempre , siempre se le dara su valor por defecto, si importar donde sea declarado o instanciado.Si es un arreglo de objetos, será null el valor de inicialización, pero si es algún tipo de dato primitivo, será su respectivo valor por default.
Los valores por defecto aquí en la inicialización de tipo integer, será cero.
Eje:class BirthDays { static int [ ] year = new int[100]; public static void main(String [] args) { for(int i=0;i<100;i++) System.out.println("year[" + i + "] = " + year[i]); }}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Variables primitivas y objetos locales
OJO: También llamadas “automáticas”, no significa que son asignados valores automáticamente, con una variable debe ser asignado un valor en el código o el compilador dará error de inicialización.
Las variables locales siempre, siempre, siempre deben ser inicializadas antes de usarlas.
Eje:public class perro { public static void main(String[] args){ int edad; System.out.println("Edad: "+edad); }}
OJO: Antes de usarla, no necesariamente cuando se las declara, esto significa que se la puede declarar, pero puede ser inicializada en otra línea.
Res: Dará error porque no se ha inicializado la variable local en el método main.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Variables primitivas y objetos locales
OJO: A veces el compilador no podra captar una inicializacion, esto se da en el caso de que la inicialización se la haga en un bloque de codigo condicional.
public class perro { public static void main(String[] args){ int edad; if ( args[0].equals("Boby") ){ edad = 1; } System.out.println("Edad: "+edad); }}
Res: Dará error, puesto que la inicialización se da dentro de una condición.
OJO: Entonces a veces así no sea necesario en la lógica, será necesario inicializar una variable para el compilador.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Referencias de Objetos Locales
El comportamiento de las referencias de objetos locales también varía un poco, puesto que aquí se lo puede dejar sin inicializar explícitamente, siempre y cuando se verifique que la variable no sea null antes de usarla.
OJO: Recordar que una variable local de referencia no inicializada, no es lo mismo, repito: no es lo mismo que asignarle null. En las variables de referencias locales.
Res: Dará error, puesto que como no ha sido inicializada la variable, no se la puede comparar con null.
Eje:public class perro { public static void main(String[] args){ String nombre; if ( nombre == null ) System.out.println("Nombre es null"); }}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Referencias de Objetos Locales
OJO: Lo que sucede es que las variables de referencia locales no se les asigna ningún valor en absoluto, osea que no es null, es nada. Esa es la razón por la que se la tiene que inicializar explícitamente a null.
public class perro { public static void main(String[] args){ String nombre = null; if ( nombre == null ) System.out.println("Nombre es null"); else System.out.println("Nombre: "+nombre); }}
Res: Nombre es null
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Arreglos Locales
Como toda variable de referencia tiene que ser inicializada. Mas no sus elementos. Se les dará sus valores por defecto.
Eje:public class perro { public static void main(String[] args){ int[] edades = new int[10]; System.out.println("Primera edad: "+edades[0]); }}
Res: Primera edad: 0
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Arreglos Locales
Como toda variable de referencia tiene que ser inicializada. Mas no sus elementos. Se les dará sus valores por defecto.
Eje:public class perro { public static void main(String[] args){ int[] edades = new int[10]; System.out.println("Primera edad: "+edades[0]); }}
Res: Primera edad: 0
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignando una variable de referencia a otra
Como toda variable de referencia tiene que ser inicializada. Mas no sus elementos. Se les dará sus valores por defecto.
Tanto en variables de primitivas como de referencia, cuando se hace una asignación de una variable a otra, lo que en realidad se esta haciendo es una copia del contenido (patrón de bits) de la variable.
Entonces tomar en cuenta que cuando se lo hace con las variables de referencia dos variables tendrán el mismo patrón de bits, osea, apuntarán al mismo objeto.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignando una variable de referencia a otra
import java.awt.Dimension; class ReferenceTest { public static void main (String [] args) { Dimension a = new Dimension(5,10); System.out.println("a.height = " + a.height); Dimension b = a; b.height = 30; System.out.println("a.height = " + a.height + " after change to b"); }}
En el ejemplo anterior podemos ver como después de la asignación a pesar de que el cambio de valor se lo hace en otra variable el valor del primer objeto cambia, esto significa que apuntan al mismo objeto.
Antes de Asignacion de variable a a variable bRes:
Despues de asignacion de variable a a variable bRes:
a.height = 10
a.height = 30
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignando una variable de referencia a otra
Una excepción para el tratamiento de variables de referencia son los String.Esto es debido a que los String son objetos inmutables, lo que significa que no se puede cambiar su valor.
class StringTest { public static void main(String [] args) { String x = "Java"; // Se asigna valor a x String y = x; // Ahora y apunta al mismo objeto de x System.out.println("y string = " + y); x = x + " Bean"; // Se modifica la referencia de x System.out.println("y string = " + y); }}
Antes de Asignacion de variable x a variable yRes:
Despues de reasignacion de variable xRes:
y string = Java
y string = Java
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignando una variable de referencia a otra
Entonces cada vez que se haga un cambio en una variable de referencia se vera afectada en cada uno de las variables que hacen referencia al objeto, pero esto no se cumple con los objetos de tipo String.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Paso por valor
La pregunta aquí es, java usa paso por valor ???La respuesta es no. Aunque por lo que se ha visto con el tratamiento de las variables de referencia, lo que en realidad se hace es un paso por valor, paso por valor de variable, lo que es en realidad un paso de la copia del valor de la variable.
Shadowing una variable
Se dice que hace shadow a una variable cuando dentro de un método se nombra a parámetro de entrada con el mismo nombre de la variable de instancia.El comportamiento difiere dependiendo si se pasa una objeto o una variable primitiva o un String.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Ejemplo de Shadowing(primitivo)
public class Zapato { static int talla = 7; static void cambiarTalla(int talla ) { talla = talla + 200; System.out.println("talla en cambiarTalla " + talla); } public static void main(String [] args) { Zapato f = new Zapato(); System.out.println("talla = " + talla); cambiarTalla(talla); System.out.println("talla despues de cambiarTalla " + talla); }}
talla = 7
Salida
talla en cambiarTalla 207
talla despues de cambiarTalla 7
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Ejemplo de Shadowing(objeto)
class Modelo{ int numeroCuartos = 2;}public class Casa { Modelo miModelo = new Modelo(); void cambiarCuartos(Modelo miModelo) { miModelo.numeroCuartos = 3; System.out.println("miModelo.numeroCuartos en cambiarCuartos es " + miModelo.numeroCuartos); miModelo = new Modelo(); miModelo.numeroCuartos = 4; System.out.println("miModelo.numeroCuartos en cambiarCuartos ahora es " + miModelo.numeroCuartos); } public static void main(String [] args) { Casa casa = new Casa(); System.out.println("casa.miModelo.numeroCuartos es " + casa.miModelo.numeroCuartos); casa.cambiarCuartos(casa.miModelo); System.out.println("casa.miModelo.numeroCuartos despues de cambiarCuartos es " + casa.miModelo.numeroCuartos); } }
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Ejemplo de Shadowing(objeto) cont…
casa.miModelo.numeroCuartos es 2
Salida
miModelo.numeroCuartos en cambiarCuartos es 3
miModelo.numeroCuartos en cambiarCuartos ahora es 4
casa.miModelo.numeroCuartos despues de cambiarCuartos es 3
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Arreglos
Primitivosint[] key; // Corchetes antes del nombre (recomendado)int key []; // Corchetes después del nombre (legal pero menos leíble)
// Espacio entre nombre y [] permitido pero mala implementación.
ObjetosThread[] hilos; // RecomendadoThread hilos[]; // Legal pero menos leible
Es recomendable seguir los consejos dados anteriormente en cuanto a la declaración de los arreglos para que puedan ser leídos y entendido mas fácilmente.
Arreglos MultidimensionalesString[][][] occupantName; // TridimensionalString[] ManagerName []; // Legal, pero muy feo y no entendible.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Arreglos
int[5] scores;
Con respecto a lo declarado, recuerden que esto nunca compilará, ya que en java hace la reservación de memoria solo en el momento de la instanciación.
Construyendo un arreglo
En el momento de la creación es donde se especifica el tamaño del arreglo para poder alojarlo en el heap.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
int[] carros; //Declara un arreglos de enteros Carros = new int[3]; //Construye un arreglo de enteros
Construyendo un Arreglo cont…
Lo que sucede en las líneas declaradas es que se crea un arreglo de enteros, luego se lo crea en memoria y después interiormente en compilador asigna ceros a todos los valores del arreglo.También se lo puede hacer en una sola línea:
int[] carros = new int[3]; // Para primitivos
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Thread[] hilos = new Thread[4]; // Para objetos
Construyendo un Arreglo cont…
Hay que tener clara la idea de lo que se ha hecho con la declaracion anterior. Tener en mente que es lo que realmente se ha hecho, no importa como se vea el codigo, el constructor de un hilo “no ha sido invocado”, lo que se ha hecho en invocar a un constructor de arreglos.Entonces lo que realmente se tiene es un contenedor de arreglos de referencias a objetos Thread, pero ninguno apunta a un Thread creado.
esta mal…
Entonces recordar que al crear un arreglo en compilador pide el tamaño, asi que si ven algo como:
int[] carList = new int[];
Nota: Construir, crear o instanciar significa lo mismo que: “Crear un objeto en el heap”
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Un arreglo multidimensional es un simple arreglo de arreglos.Así, un arreglo bidimensional de enteros es un objeto de tipo arreglo de enteros done cada uno de sus elementos es otro arreglo.
Construyendo Arreglos Multimensionales
int [][] arreglo = new int[3][];arreglo[0] = new int[3];arreglo[0][0] = 0;arreglo[0][1] = 1;arreglo[0][2] = 2;arreglo[1] = new int[2];arreglo[1][0] = 3;arreglo[1][1] = 4;
Ejemplo:
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Construyendo Arreglos Multimensionales
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Inicializar un arreglo significa que las “cosas” en el arreglo son elementos del arreglo, ya sean primitivos (enteros, strings, boleanos, etc)
Inicializando arreglos
Los objetos son accedidos mediante el numero índice que le corresponde a la posición que tiene, los índices empiezan en el numero 0 (cero).Es decir que si se tiene un arreglo de 10 elementos los índices Irán de 0 (cero) a 10 (diez).
Pero si se tiene un arreglo de objetos lo que se tiene son las “referencias” a los objetos, no los objetos en si.Es decir si se tiene un arreglos (algunos inicializados) de 5 Strings lo que se tiene es la “referencia” a esos Strings, los que no hayan sido inicializados están referenciando a null. Osea que si se trata de acceder a un método en una posición que no tiene objeto, dará NullPointerException.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Animales [] mascotas = new Animales[3];
Inicializando arreglos
Primero se declaró e inicializó el arreglo.Luego se inicializó los valores de cada uno de los elementos del arreglo.
mascotas[0] = new Animales();mascotas[1] = new Animales();mascotas[2] = new Animales();
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Tratar de ver código que busca la asignación o uso de índices que no se puede acceder por el tamaño del arreglo.Si se tiene un arreglo[3], solo se puede acceder a los elementos arreglo[0], arreglo[1] y arreglo[2], el tratar de acceder a arreglo[3] nos arrojará un ArrayIndexOutOfBoundsException, a parte de tener en cuenta los errores de compilación, también hay que tomar en cuanta a las exceptiones en Runtime.
Notas
Este último puede ser difícil de ver en un lazo complejo, pero es lo que probablemente mas se verá en el examen.
int[] x = new int[5];x[4] = 2; // OK, el ultimo elemento esta en el índice 4x[5] = 3; // Runtime exception. No hay elemento en el índice 5!int[] z = new int[2];int y = -3;z[y] = 4; // Runtime exception.; y es un numero negativo.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
A two-dimensional array (an array of arrays) can be initialized as follows:int[][] scores = new int[3][];// Declara y crea un arreglo que contiene 3 referencias a arreglos de enteros
scores[0] = new int[4];//El primer elemento en un arreglo de enteros de tamaño 4
scores[1] = new int[6];//El segundo en un arreglo de enteros de tamaño 6
scores[2] = new int[1];//El tercero es un arreglo de enteros de tamaño 1
Inicializando arreglos
Inicializando arreglos en un lazo
Los arreglos tienen un único atributo publico: length, que da el numero de elementos del arreglo.
Perro[] misPerros = new Perro[5];for (int i=0; i<misPerros.length ;i++) misPerros[i] = new Perro();
Perro[] misPerros = new Perro[5];for(Perro p : misPerros) p = new Perro();
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
int[] casas = {3,6,9};
Declarando, Construyendo e Inicializando en una línea(Atajo 1)
Para un arreglo de objetos se lo hace de la misma manera.
Aquí salta una pregunta, porque no solo se usa esta manera para crear los arreglos y la respuesta es que puede que al momento de crear el arreglo no se sepa el tamaño final.
Esta línea:• Declara una referencia de arreglo de enteros llamado casas.• Crea un arreglo de longitud tres.• Lo llena con los valores: 3,6 y 9.• Asigna el arreglo creado a la referencia de arreglo llamada casas.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Declarando, Construyendo e Inicializando en una línea
Para arreglos multidimensionales
int[][] casas = { {1,2} , {3,4,5} , {6,7,8} };
Aquí se esta creando un arreglo de arreglos, cada uno de los elementos creados es un arreglo, en donde el tamaño de estos en el número de elementos que tienen.Se ha creado 4 objetos aqui, el primer objeto creado es el arreglo de arreglos, luego el primer elemento dentro del arreglo tiene un tamaño de 2, el segundo 3 y el tercero 4, y cada uno de estos son objetos.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Perro[][] perros;perros = new Perro[][] { {new Perro()},
{new Perro(),new Perro()} };
Declarando, Construyendo e Inicializando en una línea(Atajo2)
Esta línea:• Declara una referencia de arreglo de enteros llamado casas.• Crea un arreglo de longitud tres.• Lo llena con los valores: 3,6 y 9.• Asigna el arreglo creado a la referencia de arreglo llamada casas.
Ojo: Prestar mucha atención que al momento de usar este método, ni no se especifica el tamaño de l arreglo, puesto que este está dado por el numero de elementos separados por comas.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Hasta ahora solo se ha visto asignaciones de un solo tipo de datos en un arreglo de un tipo de dato, pero que pasa si se quiere asignar un elemento de un tipo de dato distinto al del arreglo.
Asignaciones legales a elementos de Arreglos
Dentro de un arreglo se puede colocar cualquier valor que pueda ser convertido con un cast implícito al tipo de dato del arreglo.Pro ejemplo un arreglo de enteros puede contener cualquier dato que entre en una variable de 32 bits.
int[] varios = new int[5];
byte a = 1;char c = ‘a’;Short d = 3;
varios[0] = a;varios[1] = b;varios[2] = c;
Arreglos de primitivos
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Asignaciones legales a elementos de Arreglos
Si el tipo de dato del arreglo es una clase, se puede poner como elemento cualquier subclase de esta.
Animal[] mascotas = new Animal[2];mascotas[0] = new Perro();mascotas[1] = new Gato();
Arreglos de referencia a objetos
class Animal {}class Perro extends Animal{}class Gato extends Animal{}
Si el tipo de dato del arreglo es una interface, se puede poner como elemento cualquier clase que la implemente.
Mamifero[] mamiferos = new Mamifero[2];mamiferos[0] = new Perro();mamiferos[1] = new Gato();
interface Mamifero{}class Animal {}class Perro extends Animal implements Mamifero{}class Gato extends Animal implements Mamifero{}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Bloques de Inicialización
Hasta ahora de ha visto dos lugares para la ubicación de código, los constructores y los métodos. Los bloques de inicialización son el tercer lugar para esto, están los que corren cuando la clase es cargada (bloque de inicialización estático) y los que son cargadas cuando se crea una instanciación de una clase (bloque de inicialización de instanciación).
class SmallInit { static int x; int y; static { x = 7 ; } // bloque de inicialización estático { y = 8; } // bloque de inicialización de instancia}
Como se ve, no puede tomar argumentos, no puede retornar ningún valor y no tiene nombre. El bloque de inicialización estático corre una sola vez cuando la clase es cargada en la maquina virtual. El bloque de inicialización de instancia corre cada vez que es creada una nueva instancia de la clase.
Los bloques de inicialización se ejecutan justo después de la llamada al constructor de la clase padre, es decir después de la ejecución de súper, y mas generalmente corre después de la ejecución de TODOS los súper constructores.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Bloques de Inicialización
Ahora, el orden en que se ejecutan los bloques cuando hay mas de uno, es el mismo orden en que los han puesto.
Las reglas que hay que tomar en cuenta a la hora de saber como va a ser la ejecución de los bloque son:
• Los bloques se ejecutan en el orden en que aparecen.• Bloques estático son ejecutados 1 sola vez, cuando son cargados.• Bloques de instancia son ejecutados cada vez que se crea una instancia.• Bloques de instancia corren después de la llamada al súper constructor.
Ejercicio:
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Bloques de Inicialización
class Numero{ static {System.out.println("Estatico 1 Numero");} {System.out.println("Instancia 1 Numero");}}
class Real extends Numero{ static {System.out.println("Estatico 1 Real");} {System.out.println("Instancia 1 Real");}}
class Flotante extends Real{ static {System.out.println("Estatico 1 Flotante");} {System.out.println("Instancia 1 Flotante");} public Flotante(){ System.out.println("Constructor Flotante SIN Argumento"); } public Flotante(int f){ System.out.println("Constructor Flotante CON Argumento"); }}
Ejercicio:
public class Arreglos2 { static {System.out.println("Estatico 1 Arreglo2");} {System.out.println("Instancia 1 Arreglo2");} public static void main(String [] args) { System.out.println("Antes de r2"); Flotante r2 = new Flotante(1); System.out.println("Antes de r1"); Flotante r1 =new Flotante(); }}
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Bloques de Inicialización
Respuesta:
Estatico 1 Arreglo2Antes de r1Estatico 1 NumeroEstatico 1 RealEstatico 1 FlotanteInstancia 1 NumeroInstancia 1 RealInstancia 1 FlotanteConstructor Flotante SIN ArgumentoAntes de r2Instancia 1 NumeroInstancia 1 RealInstancia 1 FlotanteConstructor Flotante CON Argumento
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Clases Wrapper y Boxing
Las clases wrapper tienes dos propositos primitivos:
• Para proveer un mecanismo para envolver valores primitivos en un objeto, para que pueda ser incluidos en operaciones reservadas para objetos como: tener métodos de retorno de valores o ser puestos en una colección. Para Java 5 los métodos de autoboxing y unboxing son manejados automáticamente, lo cual se lo hacía antes manualmente.
• Proveer una variedad de utilidades para los primitivos. La mayoría de estas utilidades tienes que ver con conversiones, como: convirtiendo primitivos desde y a objetos String.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Una vista de las clases Wrapper
En java existen clases wrapper para todos los primitivos, es así que para int es Integer, boolean es Boolean, tal como se puede ver en la tabla a continuación. En la mayoria de los casos la clase wrapper tiene el nombre con la letra inicial en mayúscula, con la excepción de int que le corresponde Integer y char que le corresponde Character.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Creando Objetos Wrapper
Para el examen se tiene que entender los 3 mas comunes enfoques para la creación de estos objetos.
Algunos enfoques toman la representación en String del primitivo como argumento. Estos arrojan NumberFormatException en caso de que al primitivo no se pueda hacer la conversión. Tambien hay que tomar en cuenta que estos objetos son inmutables; una vez que se les da el valor, no se puede cambiar.
Constructor
Todas las clases wrapper, excepto Character, que provee un solo constructor, tienen dos tipos de constructores, uno que recibe el tipo de datos primitivo y el que recibe la representación en String.
Integer i1 = new Integer(42);Integer i2 = new Integer("42");
Float f1 = new Float(3.14f);Float f2 = new Float("3.14f");
Character c1 = new Character('c');
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Creando Objetos Wrapper
Para los boolean el constructor puede tomar los valores de true o flase y su respectiva representación en String. Para antes de java 5 los objetos Boolean no se podían usar como expresión en una prueba lógica.
Pero para java 5, estos si se pueden usar así, por el unboxing, del cual se va a hablar en el próximo capítulo.
El método valueOf()
Los dos métodos estáticos en la mayoría de las clases wrapper proveídas dan otro enfoque para la creación de objetos desde datos primitivos. Ambos aceptan la respectiva representación String y la segunda (cuando es proveída), toma la base en la cual esta el primer argumento que se le pasa al método.
Boolean b = new Boolean("false");if (b) //NO COMPILARÍA
Integer i2 = Integer.valueOf("101011", 2); // convierte 101011 a 43 y asigna este valor a i2
Float f2 = Float.valueOf("3.14f");
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando Utilidades de conversion
Como se dijo anteriormente la segunda gran función es convertir cosas, los siguientes métodos son los mas comúnmente usados y los mas vistos en el examen.
Cuando se quiere obtener el valor en tipo primitivo se puede usar uno de los tantos métodos xxxValue(). Todos los métodos en esta familia son métodos sin argumentos. Cada uno de los seis tipos de wrapper tienen seis métodos. De tal forma que cada wrapper numérico pueda ser convertido en un tipo numérico primitivo.
xxxValue()
Integer i2 = new Integer(42); // Crea un objeto wrapperbyte b = i2.byteValue(); // Convierte el valor de i2 a bytes primitivos.short s = i2.shortValue(); double d = i2.doubleValue();
Float f2 = new Float(3.14f); // Crea objeto wrappershort s = f2.shortValue(); // Devuelve valor short primitivo.
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando Utilidades de conversion
El metodo parseXxx() de cada uno de las clases wrapper numericas esta estrechamente relacionado con la clase valueOf(), los dos aceptan un String como argumento y arrojan NumberFormatException si es que el argumento no esta bien formado, y pueden convertir objetos String en otras bases. La diferencia entre los dos métodos son:
parseXxx() and valueOf()
• parseXxx() retorna un tipo de datos primitivo, correspondiente a la clase que los invoca.
• valueOf() retorna un nuevo objeto wrapper creado del mimo tipo de la clase que lo implementa.
Eje:double d4 = Double.parseDouble("3.14"); // Convierte un String a un primitivoDouble d5 = Double.valueOf("3.14"); // Crea un nuevo objeto wrapper.System.out.println(d5 instanceof Double); // Resultado es “verdadero”
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando Utilidades de conversion
parseXxx() and valueOf() (continuation…)
Dada que la clase Object, la clase Alpha tiene un metodo toString() y que toda clase hereda de la clase Object, por lo tanto estas clases wrapper tambien van a tener este metodo sin argumento y no estatico. La idea de esta clase es que se devuelva una representacion significativa del objeto.
Eje:long L2 = Long.parseLong("101010", 2); // String binario a primitivoLong L3 = Long.valueOf("101010", 2); // String binario a objeto wrapperSystem.out.println("L3 value = " + L3); // Resultado es “verdadero”
toString()
Double d = new Double("3.14");System.out.println("d = "+ d.toString() ); // resultado es d = 3.14
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando Utilidades de conversión
Todo objeto wrapper numérico contiene un método estático y sobrecargado toString() , el cual toma como argumento un tipo de dato primitivo numérico y retorna su representación en String.
toString() (continuation…)
Finalmente Integer y Long proveen un método toString() que toma dos argumentos, el primero de tipo primitivo numérico y el segundo es un radix, este le dice al método en que base devolver el primer argumento.
String d = Double.toString(3.14); // d = "3.14"
String s = "hex = "+ Long.toString(254,16); // s = "hex = fe"
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Usando Utilidades de conversión
Las clases wrapper Integer y Long permiten números en base 10 a otras bases. Toman un int o long y retornan su respectiva representación String.
toXxxString()
String s = "hex = "+ Long.toString(254,16); // s = "hex = fe"
String s3 = Integer.toHexString(254); // Convierte 254 a hexSystem.out.println("254 is " + s3); // Resultado: "254 is fe"String s4 = Long.toOctalString(254); // Convierte 254 a octalSystem.out.print("254(oct) ="+ s4); // Resultado: "254(oct) =376“String s5 = Long.toBinaryString(5);System.out.print(“5(bin) ="+ s5); // Resultado: "5(bin) =101“
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Tabla de Resumen
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Autoboxing
Nuevo en Java 5, conocido como autoboxing, auto-unboxing, boxing y unboxing, se manejara con los terminos boxing y unboxing. Esto hace el manejo de las clases wrapper mas conveniente.Por ejemplo, si antes se queria hacer una wrapper, y luego se queria sacar el valor, aumentarlo y volverlo a poner, se tenia que hacer algo como:
Ahora con el mejorado Java 5, se hace lo siguiente:
Integer y = new Integer(567); // Crearloint x = y.intValue(); // Sacarlox++; // Aumentarloy = new Integer(x); // Volverlos a meterSystem.out.println("y = " + i); // Se lo imprime
Integer y = new Integer(567); // Crearloy++; // Sacarlo, aumentarlo.
// MeterloSystem.out.println("y = " + i); // Se lo imprime
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Autoboxing
Por detrás del escenario, el compilador hace unboxing y reasignamiento a la variable.Aunque con lo mostrado parece contradecirse con lo anteriormente escrito, con respecto a que el valor de una clase wrapper es inmutable, lo que en realidad se hace es crear una nueva clase wrapper y reasignarla.Para verificar lo dicho se lo puede demostrar con la siguiente prueba.
Integer y = 567; // Crear el wrapperInteger x = y; // Asginarlo a otra referenciaSystem.out.println(y==x); // Verificar si es el mismo objetoy++; // Aplicar la operaciónSystem.out.println(x + " " + y); // Se imprime los valoresSystem.out.println(y==x); // Verificar si es el mismo objeto.
true567 568false
Resultado:
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Boxing, ==, and equals()
En el ejemplo anterior se usó ==, pero también están != y el método equals(). Mas adelante se verá mucho mas que el método equals(), por ahora solo tenemos que saber que la intención este método es saber cuando dos objetos son “iguales de maneta significativa”. La definición es intencionalmente subjetiva, ya que depende del creador de la clase determinar a que es equivalente. Los desarrolladores del API decidieron que para todas las clases wrapper, dos objetos son iguales si es que son del mismo tipo y tienen el mismo valor. Es así que aquí está un ejemplo:
Integer i1 = 1000;Integer i2 = 1000;if(i1 != i2) System.out.println("different objects");if(i1.equals(i2)) System.out.println("meaningfully equal");
different objectsmeaningfully equal
Resultado:
Sun Certified Java Programmer (SCJP)
Carlos Oñate Bravo
Boxing, ==, and equals()
Y ahora este:
Y que pasó aquí? Por que si antes con el mismo valor dio que los objetos eran distintos, ahora me dice que con mismo valor, los dos objetos son iguales???Lo que pasa es que para ahorrar memoria cuando dos instancias tienen el mismo valor de las siguientes clases, se apunta a la misma instancia.
Integer i3 = 10;Integer i4 = 10;if(i3 == i4) System.out.println("same object");if(i3.equals(i4)) System.out.println("meaningfully equal");
Resultado:
same objectmeaningfully equal
BooleanByteCharacterShort e Integer