La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Sun Certified Java Programmer (SCJP) Capítulo 3: Asignaciones

Presentaciones similares


Presentación del tema: "Sun Certified Java Programmer (SCJP) Capítulo 3: Asignaciones"— Transcripción de la presentación:

1 Sun Certified Java Programmer (SCJP) Capítulo 3: Asignaciones

2 Stack - Heap (Vista Rápida)

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

4 Stack – Heap Ejemplo: class Collar{} 1. public class Perro {
2. Collar c; 3. private String nombre; 4. public static void main(){ Perro perro; perro = new Perro(); perro.setNombre("Bobby"); 8. } 9. public void andar(Perro p){ c = new Collar(); p.setNombre("bobby"); } public void setNombre(String nombrePerro) { this.nombre = nombrePerro; } 16.}

5 Stack – Heap Lo que sucede: Linea 4 - main() va al stack.
Linea perro es puesto en el stack. Linea 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.

6 Literales, Asignaciones y Variables (Objetivos del examen)
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 =,+=,-= 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 char 42 // literal int false // literal boolean // literal double

7 Literales Integer Literal Decimal
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.

8 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: z: -1 Resp: a:

9 Literales Punto-Flotante
Son definidos como un numero, un símbolo de decimal y mas numero representando la fracción. Eje: double d = ; 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 = f; 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.

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

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

12 Literales Caracteres Valores de Literales String
Se los representa en la forma mas sencilla con comillas dobles. Eje: String string = “hola”;

13 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 , representado por 8 bits. Pero no pasa lo mismo con las variables de referencia a Objetos, las cuales son solo eso, variables de referencia.

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

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

16 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. Eje: Implícito int i = 1; float f = i; double d = 100L; Explicito float f = f; int i = (int)f; ==> perdida de precisión. int id = (int) ; ==> perdida de precisión. se pierden todos los decimales.

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

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

19 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 Para que pase a un byte, se deja solo 8 bits, sabiendo que el mas de la izquierda representa el signo. Así solo queda ==> Negativo A lo que se le saca el complemento a dos, para secar el número negativo, lo que nos da ==> 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é.

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

21 Asignación a una Variable de Referencia
Si se tiene Button 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.

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

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

24 Alcance de una variable
Entonces tenemos: s – variable estatica. X – variable de instancia Y – variable local Z – variable de bloque X2 – 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: Variable estáticas que son las que mas sobreviven, empiezan cuando la clase es cargada, hasta que dure en la JVM 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. 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 bloque, que viven mientras en bloque de código es ejecutado.

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

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

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

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

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

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

31 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(); Dará un error, puesto que se tratara de aplicar un método de conversión a un valor null. 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á.

32 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. 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]); } Los valores por defecto aquí en la inicialización de tipo integer, será cero.

33 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. 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. Eje: public class perro { public static void main(String[] args){ int edad; System.out.println("Edad: "+edad); } Res: Dará error porque no se ha inicializado la variable local en el método main.

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

35 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. Eje: public class perro { public static void main(String[] args){ String nombre; if ( nombre == null ) System.out.println("Nombre es null"); } Res: Dará error, puesto que como no ha sido inicializada la variable, no se la puede comparar con null.

36 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

37 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

38 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

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

40 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"); } Antes de Asignacion de variable a a variable b Res: a.height = 10 Despues de asignacion de variable a a variable b Res: a.height = 30 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.

41 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 } Antes de Asignacion de variable x a variable y Res: y string = Java Despues de reasignacion de variable x Res: y string = Java

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

43 Shadowing una variable
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.

44 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); Salida talla = 7 talla en cambiarTalla 207 talla despues de cambiarTalla 7

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

46 Ejemplo de Shadowing(objeto) cont…
Salida casa.miModelo.numeroCuartos es 2 miModelo.numeroCuartos en cambiarCuartos es 3 miModelo.numeroCuartos en cambiarCuartos ahora es 4 casa.miModelo.numeroCuartos despues de cambiarCuartos es 3

47 Arreglos Primitivos int[] 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. Objetos Thread[] hilos; // Recomendado Thread 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 Multidimensionales String[][][] occupantName; // Tridimensional String[] ManagerName []; // Legal, pero muy feo y no entendible.

48 Construyendo un arreglo
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.

49 Construyendo un Arreglo cont…
int[] carros; //Declara un arreglos de enteros Carros = new int[3]; //Construye un arreglo de enteros 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

50 Construyendo un Arreglo cont…
Thread[] hilos = new Thread[4]; // Para objetos 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. Entonces recordar que al crear un arreglo en compilador pide el tamaño, asi que si ven algo como: int[] carList = new int[]; esta mal… Nota: Construir, crear o instanciar significa lo mismo que: “Crear un objeto en el heap”

51 Construyendo Arreglos Multimensionales
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. Ejemplo: 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;

52 Construyendo Arreglos Multimensionales

53 Inicializando arreglos
Inicializar un arreglo significa que las “cosas” en el arreglo son elementos del arreglo, ya sean primitivos (enteros, strings, boleanos, etc) 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. 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).

54 Inicializando arreglos
Animales [] mascotas = new Animales[3]; mascotas[0] = new Animales(); mascotas[1] = new Animales(); mascotas[2] = new Animales(); Primero se declaró e inicializó el arreglo. Luego se inicializó los valores de cada uno de los elementos del arreglo.

55 Notas 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. int[] x = new int[5]; x[4] = 2; // OK, el ultimo elemento esta en el índice 4 x[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. Este último puede ser difícil de ver en un lazo complejo, pero es lo que probablemente mas se verá en el examen.

56 Inicializando arreglos
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 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();

57 Declarando, Construyendo e Inicializando en una línea (Atajo 1)
int[] casas = {3,6,9}; 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. 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. Para un arreglo de objetos se lo hace de la misma manera.

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

59 Declarando, Construyendo e Inicializando en una línea (Atajo2)
Perro[][] perros; perros = new Perro[][] { {new Perro()}, {new Perro(),new Perro()} }; 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.

60 Asignaciones legales a elementos de Arreglos
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. Arreglos de primitivos 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;

61 Asignaciones legales a elementos de Arreglos
Arreglos de referencia a objetos Si el tipo de dato del arreglo es una clase, se puede poner como elemento cualquier subclase de esta. class Animal {} class Perro extends Animal{} class Gato extends Animal{} Animal[] mascotas = new Animal[2]; mascotas[0] = new Perro(); mascotas[1] = new Gato(); Si el tipo de dato del arreglo es una interface, se puede poner como elemento cualquier clase que la implemente. interface Mamifero{} class Animal {} class Perro extends Animal implements Mamifero{} class Gato extends Animal implements Mamifero{} Mamifero[] mamiferos = new Mamifero[2]; mamiferos[0] = new Perro(); mamiferos[1] = new Gato();

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

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

64 Bloques de Inicialización
Ejercicio: 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"); 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(); }

65 Bloques de Inicialización
Respuesta: Estatico 1 Arreglo2 Antes de r1 Estatico 1 Numero Estatico 1 Real Estatico 1 Flotante Instancia 1 Numero Instancia 1 Real Instancia 1 Flotante Constructor Flotante SIN Argumento Antes de r2 Constructor Flotante CON Argumento

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

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

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

69 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. Boolean b = new Boolean("false"); if (b) //NO COMPILARÍA 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. Integer i2 = Integer.valueOf("101011", 2); // convierte a 43 y asigna este valor a i2 Float f2 = Float.valueOf("3.14f");

70 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. xxxValue() 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. Integer i2 = new Integer(42); // Crea un objeto wrapper byte 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 wrapper short s = f2.shortValue(); // Devuelve valor short primitivo.

71 Usando Utilidades de conversion
parseXxx() and valueOf() 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() 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 primitivo Double d5 = Double.valueOf("3.14"); // Crea un nuevo objeto wrapper. System.out.println(d5 instanceof Double); // Resultado es “verdadero”

72 Usando Utilidades de conversion
parseXxx() and valueOf() (continuation…) Eje: long L2 = Long.parseLong("101010", 2); // String binario a primitivoLong L3 = Long.valueOf("101010", 2); // String binario a objeto wrapper System.out.println("L3 value = " + L3); // Resultado es “verdadero” toString() 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. Double d = new Double("3.14"); System.out.println("d = "+ d.toString() ); // resultado es d = 3.14

73 Usando Utilidades de conversión
toString() (continuation…) 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. String d = Double.toString(3.14); // d = "3.14" 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 s = "hex = "+ Long.toString(254,16); // s = "hex = fe"

74 Usando Utilidades de conversión
toXxxString() 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. String s3 = Integer.toHexString(254); // Convierte 254 a hex System.out.println("254 is " + s3); // Resultado: "254 is fe" String s4 = Long.toOctalString(254); // Convierte 254 a octal System.out.print("254(oct) ="+ s4); // Resultado: "254(oct) =376“ String s5 = Long.toBinaryString(5); System.out.print(“5(bin) ="+ s5); // Resultado: "5(bin) =101“ String s = "hex = "+ Long.toString(254,16); // s = "hex = fe"

75 Tabla de Resumen

76 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: Integer y = new Integer(567); // Crearlo int x = y.intValue(); // Sacarlo x++; // Aumentarlo y = new Integer(x); // Volverlos a meter System.out.println("y = " + i); // Se lo imprime Ahora con el mejorado Java 5, se hace lo siguiente: Integer y = new Integer(567); // Crearlo y++; // Sacarlo, aumentarlo. // Meterlo System.out.println("y = " + i); // Se lo imprime

77 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 wrapper Integer x = y; // Asginarlo a otra referencia System.out.println(y==x); // Verificar si es el mismo objeto y++; // Aplicar la operación System.out.println(x + " " + y); // Se imprime los valores System.out.println(y==x); // Verificar si es el mismo objeto. Resultado: true false

78 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"); Resultado: different objects meaningfully equal

79 Boxing, ==, and equals() Y ahora este: Integer i3 = 10;
if(i3 == i4) System.out.println("same object"); if(i3.equals(i4)) System.out.println("meaningfully equal"); Resultado: same object meaningfully equal 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. Boolean Byte Character Short e Integer


Descargar ppt "Sun Certified Java Programmer (SCJP) Capítulo 3: Asignaciones"

Presentaciones similares


Anuncios Google