oracle certified professional java se 6 programmer 3

50
México Distrito Federal a 08 de Marzo de 2014 Autor: Pablo Galeana Bailey Cualquier duda y/o comentario quedo a sus órdenes para alguna asesoría o recomendación para mejorar el presente material. Email: [email protected] Capítulo 3 - Asignaciones 1. Stack y Heap -- Rápido repaso La mayor parte de las variables, métodos y objetos en un programa Java se alojan en dos memorias diferentes: Stack o Heap. Por ahora nosotros vamos a tratar tres tipos de cosas: variables de instancia, variables locales y objetos: Las variables de instancia y los objetos se almacenan en la memoria Heap. Las variables locales se colocan en la memoria Stack.

Upload: pablo-galeana-bailey

Post on 12-Jun-2015

453 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Oracle certified professional  java se 6 programmer 3

México Distrito Federal a 08 de Marzo de 2014

Autor: Pablo Galeana Bailey

Cualquier duda y/o comentario quedo a sus órdenes para alguna asesoría orecomendación para mejorar el presente material.

Email: [email protected]

Capítulo 3 - Asignaciones1. Stack y Heap -- Rápido repasoLa mayor parte de las variables, métodos y objetos en un programa Java se alojanen dos memorias diferentes: Stack o Heap.Por ahora nosotros vamos a tratar tres tipos de cosas: variables de instancia,variables locales y objetos: Las variables de instancia y los objetos se almacenan en la memoria

Heap. Las variables locales se colocan en la memoria Stack.

Page 2: Oracle certified professional  java se 6 programmer 3

Ejemplo un programa Java y la manera en que se almacenan en la Stack o Heap:

En la siguiente figura se visualiza donde se almacena cada elemento:

2.1. Valores literales para todos los tipos PrimitivosUn literal primitivo es simplemente una representación en código de los tipos dedatos primitivos, en otras palabras, un número entero, punto flotante, booleano ocarácter.Los siguientes ejemplos son literales primitivos:

Page 3: Oracle certified professional  java se 6 programmer 3

EnterosHay tres maneras de representar un entero en el lenguaje Java: decimal,octal y hexadecimal. La mayoría de las preguntas son con literales enteros endecimal, pero las pocas que usan octal o hexadecimal son necesariasestudiársela.

DecimalesEn el lenguaje Java se representan, sin prefijo de ningún tipo, como lo siguiente:

OctalesLos enteros octales solo usan números del 0 al 7. En Java, se representancolocando un 0 delante del número, como vemos a continuación:

Un número octal puede tener 21 dígitos no incluyendo el cero del comienzo. Siejecutamos el anterior código, nos mostrara lo siguiente: Octal 010 = 8

HexadecimalesLos números hexadecimales son construidos usando 16 símbolos diferentes. Losnúmeros del 10 al 15 son caracteres alfabéticos que representan a los dígitos. Losdiferentes símbolos son:0 1 2 3 4 5 6 7 8 9 a b c d e f

Java aceptara mayúsculas o minúsculas para los dígitos extras (uno de lospocos lugares de Java que no es case-sensitive). Se permiten 16 dígitos en unhexadecimal, sin contar el prefijo 0x o el sufijo opcional L.Todas las siguientes asignaciones de decimales son legales:

Page 4: Oracle certified professional  java se 6 programmer 3

La salida sería la siguiente:X = 1 y = 2147483647 z = -559035650

No te dejes engañar por las minúsculas y mayúsculas en un dígitohexadecimal, 0XCAFE y 0xcafe son ambos legales y tienen idéntico valor.Los tres literales enteros son definidos como int por defecto, pero también seránespecificados como long colocando un sufijo de L o l detrás del número:

Punto-flotanteLos números en punto-flotante son definidos como un número, un símbolo decimal(punto) y mas números representando la fracción.double d = 11301874.9881024;

En el ejemplo anterior, el número 11301874.9881024 es el valor literal. Los punto-flotante son definidos por defecto como doublé (64 bits), así que si tú quieresasignar un punto-flotante a una variable de tipo float (32 bits), entonces debesponer el sufijo L o l al número:

También podríamos opcionalmente poner D o d cuando es double, pero no esnecesario porque es su tipo por defecto:

Si en vez del carácter punto ponemos una coma el código no compilara:

BooleanosUn booleano puede valer true o false únicamente.Aunque en C es común usar números para representar true o false, esto noes posible en Java.

Estar atento a las preguntas en las que un número este en el lugar quedebería estar un booleano, por ejemplo como en el siguiente código:

Page 5: Oracle certified professional  java se 6 programmer 3

CarácterUn carácter está representado por un único carácter entre comillas simples.

También se puede escribir el valor UNICODE del carácter, usando la notaciónUNICODE con \u como prefijo.

Recuerda, los caracteres son enteros de 16 bits sin signo. Los siguientes ejemplosson todos legales:

Y los siguientes son erróneos y producen errores de compilación:

También pueden usar un código de escape si tú quieres representar un carácterque no pueda escribirse en un literal, incluyendo los caracteres fin de línea, nuevalínea, horizontal tab, backspace y comillas simples.

Valores literales para StringUn literal String es la representación en código de un objeto String. Por ejemplo, losiguiente son dos formas diferentes de representar un literal String:

Aunque los String no son primitivos, están incluidos en esta sección porquepueden ser representados como literales. Es el único tipo no primitivo juntocon el array que tiene una representación literal:

2.2. Asignación de operadoresLas variables son solo bits, al que se le asigna un tipo. Pueden ser int,double, Button e incluso String[].Para los primitivos, los bits representan un valor numérico. UN byte convalor 6, por ejemplo, significa que el patrón en la variable es 00000110,representando los 8 bits.

Un variable referenciando a un objeto es solo una variable de referencia. Unavariable de referencia contiene bits que representan la manera de poder

Page 6: Oracle certified professional  java se 6 programmer 3

obtener el objeto. Si la variable de referencia no tiene asignado un valor, o a sidoalmacenado explícitamente el valor de null, la variable se representa con null. Porejemplo:

Aquí podemos ver que La variable Button b no está referenciando a ningún objeto.

Asignaciones PrimitivosEl signo igual (=) es usado para asignar un valor a una variable y es llamado signode asignación.Actualmente hay 12 operados de asignación, pero solo entran en el examenlos cinco usados más comúnmente y estos se cubrirán en el Capítulo 4.Puedes asignar una variable primitiva usando un literal o el resultado de unaexpresión. Como podemos ver a continuación:

El punto más importante que debemos recordar es que un literal entero (como 7)es siempre implícitamente un int. El siguiente código es legal:

Este código es legal porque el compilador automáticamente limito el valor delliteral a un byte. En otras palabras, el compilador hizo un casting.El siguiente código es idéntico al anterior:

Un entero literal es siempre un int, pero aún más importante es que elresultado de una expresión que envuelva tamaños int o más pequeños essiempre un int.Es decir, si sumo dos bytes obtendré un int (incluso si esto bytes son diminutos), simultiplico un int y un short obtengo un int, si divido un short entre un byte obtendréun int,....etc. Ejemplo:

La última línea no compilara. Obtendremos un error como el siguiente:TestBytes.java:5: possible loss of precisionfound : int required: byte byte c = a + b;Estamos intentando asignar la suma de dos bytes a otra variable byte, el resultado(11) definitivamente fue lo suficientemente pequeño como para caber en un byte,pero el compilador no tuvo cuidado. Para que compilase deberíamos haber hechoun casting explícitamente.

Page 7: Oracle certified professional  java se 6 programmer 3

Casting primitivosHacer un casting te permite convertir valores primitivos desde un tipo a otro.Los casting pueden ser implícitos o explícitos.Un casting implícito significa que no tienes que escribir en código el casting, laconversión se provoca automáticamente.Un valor largo en un contenedor pequeño requiere un casting explicito, donde leindiques al compilador que tu asumes toda la responsabilidad de perdidas.Primero veremos castings implícitos.

A continuación unos castings explícitos:

Los valores enteros pueden ser asignados a una variable double sin castingexplicito. Las siguientes líneas demuestran esto:

En la sentencia anterior, un double esta inicializado con un valor long. El castingno es necesario porque un double puede contener cualquier información que unlong pueda almacenar. Si, sin embargo, queremos asignar un valor double a untipo entero, nosotros estamos intentando una reducción de conversión y elcompilador lo sabe:

Si nosotros intentamos compilar el anterior código, obtendremos un error similar alsiguiente:%javac Casting.javaCasting.java:3: Incompatible type for declaration. Explicit castneeded to convert double to int.int x = 3957.229; illegal1 error

Para que esto funcione, debemos hacer un casting de número en punto flotante aentero.

Page 8: Oracle certified professional  java se 6 programmer 3

Al hacer el casting pierdes todo la parte decimal y el resultado sería: int x = 3957

Es permitido hacer un casting de un tipo de número largo, como long, dentro de untipo de número más pequeño, como puede ser byte. Fíjate en lo siguiente:

El código anterior compilara y se ejecutar bien. Pero qué pasa si el valor long esmayor que 127 (el mayor número que un byte puede almacenar). Vamos amodificar el código:

El código compilara bien y cuando nosotros ejecutemos obtendremos lo siguiente:%java CastingThe byte is -126

No obtendremos un error en tiempo de ejecución, incluso cuando el valor que estásiendo reducido es demasiado grande para el tipo. Si el bit mas a la izquierda (elbit de signo) en el byte (o en cualquier entero primitivo) ahora pasa a ser un uno,el primitivo tendrá un valor negativo.

Asignando números Punto-FlotanteLos números en punto-flotante implícitamente son double (64 bits), no un float. Asíque el literal 32.3, es considerado un double. SI intentas asignar un double a unfloat, el compilador sabrá que tú no tienes suficiente espacio en un contenedorfloat de 32 bitas para mantener la precisión de un double de 64 bits.El siguiente código parece bueno, pero no compilara.

Puedes ver que 32.3 podría ajustarse bien a una variable de tamaño float, pero el

Page 9: Oracle certified professional  java se 6 programmer 3

compilador no te lo permite. Con el fin de asignar un literal punto flotante a unavariable float, tú debes hacer un casting o poner al final del número la letra f. Lassiguientes asignaciones compilaran:

Asignación de un literal más grande que la variableTambién obtendremos un error de compilación si intentamos asignar un valorliteral que el compilador sabe que es mayor que el tamaño de la variable.

El anterior código da un error similar al siguiente:TestBytes.java:5: possible loss of precisionfound : intrequired: bytebyte a = 128;

Podemos arreglarlo con un casting:

Para asignarle 128 a un byte debes hacerle un casting de manera explícita, pero laasignación será de -128. Haciendo el casting solo le decimos al compilador queestamos de acuerdo con la asignación.Esto nos lleva a la asignación de operador compuesto. El siguiente códigocompilara:

Y es equivalente a:

El operador de asignación compuesto += permite sumar el valor de b, sin poner uncasting explicito. De hecho, +=,-=,* y / ponen el casting de manera implícita.

Asignación de una variable primitiva a otra variable primitivaAl asignar una variable primitiva a otra, los contenidos de la variable de la derechason copiados. Por ejemplo:

En este punto, "a" y "b" tienen idéntico contenido (en otras palabras, idénticovalor), pero si cambiamos el contenido de alguna de ellas, la otra no se veráafectada. Ejemplo:

Page 10: Oracle certified professional  java se 6 programmer 3

La salida del anterior programa es:%java ValueTesta = 10a = 10 after change to b

El punto clave que debemos comprender es que siempre después de asignar auna variable otra, las variables no se refieren al mismo lugar de memoria. Lasvariables "a" y "b" son copias idénticas.

Asignación de variables de referenciaTú puedes asignar un nuevo objeto creado a una variable de referencia al objetocomo:

La línea anterior tiene tres cosas claves: Crear una variable de referencia denominada "b", de tipo Button. Crear un nuevo Button en la memoria Heap. Asignar el nuevo objeto Button creado a la variable b.

También se puede asignar null a una variable de referencia a un objeto, quesimplemente significa que la variable no está referenciando a ningún objeto:

La línea anterior crea espacio para la variable de referencia de tipo Button, pero nocrea un objeto Button. Se puede usar una variable de referencia para referirse acualquier objeto que sea una subclase del tipo de la variable de referencia, comopodemos ver en lo siguiente:

Page 11: Oracle certified professional  java se 6 programmer 3

La regla es que puedes asignar una subclase del tipo declarado, pero no unasuperclase. Un objeto Bar tiene las garantías de poder hacer algo que puedahacer Foo, de modo que cualquiera con una referencia Foo puede invocarlos métodos aunque el objeto es en realidad un Bar.

En el código anterior Foo tiene un método doFooStuff() que alguien con unareferencia Foo podría tratar de invocar. Si el objeto referenciado por la variableFoo es en realidad un Foo, no hay problemas. Pero tampoco hay problemas si elobjeto es un Bar, ya que desde Bar heredamos el método doFooStuff(). No sepodría hacer a la inversa, si alguien tiene una referencia Bar, puede invocar almétodo doBarStuff(), pero si el objeto es un Foo, no sabría cómo responder.

2.3. Ámbito de VariableVamos a empezar por la estructura de la siguiente clase:

Page 12: Oracle certified professional  java se 6 programmer 3

Al igual que con las variables en todos los programas Java, las variables en esteprograma (s, x, x2, x3, y y z) tienen un ámbito: s es una variable estática. x es una variable de instancia. y es una variable local (algunas veces denominada variable de método local). z es una variable bloque. x2 es una variable de inicialización de bloque, un tipo de variable local. x3 es una variable de construcción, un tipo más de variable local.

Existen cuatro ámbitos básicos. Las variables estáticas tienen el mayor ámbito, son creadas cuando la clase

es cargada y viven siempre y cuando la clase este cargada en la JVM. Las variables de instancia son las siguientes que tienen mayor vida, son

creadas cuando una nueva instancia ha sido creada y viven hasta que lainstancia es eliminada.

Las variables locales, viven durante el tiempo que el método está en lamemoria Stack. Sin embargo, pronto veremos que las variables locales puedenestar vivas estando fuera del ámbito.

Las variables de bloque viven solo durante la ejecución del bloque de código.

Un error común sucede cuando una variable es shadowed (sombra) y dosámbitos se solapan. Más adelante tendremos más detalles de shadowing. Larazón más común para los errores de ámbito es cuando accedes a unavariable que no está en el ámbito.Ejemplo: Intentando acceder a una variable de instancia desde un contexto

estático (normalmente desde main()).

Intentando acceder a una variable local desde un método anidado.Cuando un método, por ejemplo go(), invoca a otro método, go2(), el método go2()no tiene acceso a las variables locales de go(). Mientras go2() se esté ejecutando,las variables locales de go() siguen vivas, pero están fuera del ámbito.Cuando go2() se termine, será eliminado de la memoria Stack y go() reanudara suejecución. Una vez llegados a este punto, todas las variables declaradaspreviamente volverán a estar en el ámbito.

Page 13: Oracle certified professional  java se 6 programmer 3

Por ejemplo:

Intentando hacer uso de una variable de bloque después de que el códigode bloque se haya terminado.

Es muy común declarar y usar una variable dentro de un bloque de código, peroten cuidado de no intentar usar la variable una vez el bloque haya terminado:

En los dos ejemplos anteriores, el compilador manda error: cannot find symbol

La variable a la que está intentando acceder, podría haber sido valido en otraparte del código (como por ejemplo una línea de código anterior) o no tiene en lamemoria dicha variable.

2.5. Variables de instancia de tipo primitivo y ObjectLas variables de instancia (también llamadas variable miembro) son aquellasdefinidas en el nivel de la clase.Esto significa que la declaración de la variable no se hace dentro de un método,constructor o cualquier otro bloque inicializador. Las variables de instancia soninicializadas con un valor por defecto cada vez que una nueva instancia es creada,aunque podrá ser sometido a un valor explicito después de que el super-constructor del objeto se haya completado.

Page 14: Oracle certified professional  java se 6 programmer 3

La siguiente tabla muestra los valores por defecto para los tipos primitivos yObject.

Tipo variable Valor por defectoObjeto referencia null(sin referenciar cualquier objeto)float, double 0.0boolean falsechar '\u0000'byte, short, int, long 0

2.6. Instanciar Variables PrimitivasEn el siguiente ejemplo, la variable year de tipo entero es definida como unmiembro de clase ya que esta dentro de las llaves iníciales de la clase y no dentrode las llaves de un método:

Cuando empieza el programa, le da un valor cero a la variable year, por defecto elvalor para variables de instancias primitivas.

2.7. Instanciar Variables de referencia a ObjetosLas referencias de Objetos que no están inicializadas son completamentediferentes. Fíjate en el siguiente código:

Este códigocompilara bien, la salida será: The title is null

La variable "title" no ha sido inicializada explícitamente con un String, así que elvalor de la variable de instancia es null. Recordar que nulo no es lo mismo que

Page 15: Oracle certified professional  java se 6 programmer 3

un String vacío (""). Un valor nulo significa que la variable no está referenciandoa ningún objeto en la memoria Heap.La siguiente modificación del código se ejecutará con errores:

Al ejecutar la clase Book, producirá lo siguiente:Exception in thread "main" java.lang.NullPointerExceptionat Book.main(Book.java:9)

El error es porque la referencia de la variable "title" no apunta a un objeto.Podemos comprobar haber si el objeto ha sido inicializado usando la palabra clavenull, así como vemos en el siguiente código:

Ten cuidado en el examen donde deberías tener que rastrear a través delcódigo para encontrar si una referencia a objeto tendrá un valor nulo.En el anterior código, por ejemplo, buscas la declaración de la variable deinstancia title, veras que no hay inicialización explicita, reconoces que la variabletitle tendrá el valor por defecto null y luego darse cuenta que la variable "s"también tendrá un valor null. Recordar, el valor de "s" es una copia del valor de"title", así que su "title" es una referencia nula, "s" también lo será.

2.8. Variables de instancia ArrayLos elementos de un array siempre, siempre obtienen valores por defecto,independientemente de donde el array haya sido declarado o instanciado.Si inicializamos un array, los elementos serán igual a null si no están inicializadosindividualmente con valores.

Page 16: Oracle certified professional  java se 6 programmer 3

Ejemplo:

La salidaindicará que los 100 enteros en el array son iguales a cero.

2.9. Variables locales (Stack, automatic) Primitivas y objetos Variables locales primitivas

El entero "year" está definido como una variable automática porque se encuentradentro de las llaves de un método.

Las variables locales, incluyendo las primitivas, siempre deben serinicializadas antes de intentar usarlas (aunque no necesariamente en lamisma línea de código).

Si intentas usar una variable primitiva sin inicializar, obtendrás un error delcompilador:

Al compilar produce una salida similar a la siguiente:%javac TimeTravel.JavaTimeTravel.java:4: Variable year may not have been initialized.System.out.println("The year is " + year);1 error

Para corregir nuestro código, le debemos dar al entero "year" un valor. En esteejemplo actualizado, declaramos la variable en una línea diferente a lainicialización, que es perfectamente válido:

Page 17: Oracle certified professional  java se 6 programmer 3

Puedes declarar una variable local mientras no uses dicha variable.

Observar el siguiente ejemplo:

El compilador producirá un error similar al siguiente:TestLocal.java:9: variable x might not have been initialized

Debido a que el compilador no puede indicarte ciertos problemas, algunas vecesnecesitas inicializar tu variable fuera del bloque condicional.

Variables Locales de Referencias a ObjetosLas referencias a objetos, también, se comportan de diferente maneracuando se declara en un método en lugar de declararlas como variables deinstancia.Para el compilador, null es un valor. No puedes usar el operador punto (.) en unareferencia con valor null, ya que no referencia ningún objeto, una referencia convalor null no es lo mismo que una referencia sin inicializar.Las referencias declaradas localmente no pueden hacer una comprobación denulos antes de usarlo, a menos que inicialices de manera explícita la variable locala null. Ejemplo:

Page 18: Oracle certified professional  java se 6 programmer 3

El resultado de la compilación del código da un error similar al siguiente:%javac TimeTravel.javaTimeTravel.java:5: Variable date may not have been initialized.if (date == null)1 error

Las referencias que son variables de instancia siempre obtienen un valor pordefecto null, hasta que implícitamente se inicialice con otra cosa.Las referencias locales no obtienen un valor por defecto, en otras palabras.no son nulas. Hay que establecer explícitamente las referencias con el valor null,hasta tu estar listo para inicializarla con otra cosa. La siguiente variable localcompilara apropiadamente:

Variables Locales ArraysNo necesitas inicializar explícitamente los elementos de una array. Lo hemosdicho anteriormente: los elementos de los arrays obtienen sus valores pordefecto independientemente de si el array es declarado como una instanciao como una variable local. El objeto array no será inicializado si es declaradolocalmente. En otras palabras, debes explícitamente inicializar un array referenciasi es declarado y usado dentro de un método, pero en el momento de construir unobjeto array.

2.10. Asignando una variable referencia a otraLos contenidos de una variable de referencia son un patrón de bits, así que siasignas la variable de referencia "a" a la variable de referencia "b", el patrón debits de "a" es copiado y almacenado en "b". Si asignamos una instancia existentede un objeto a una nueva variable de referencia, ambas tendrán el mismo patrónde bits (un patrón de bits referenciando a un objeto específico de la memoriaHeap.

Page 19: Oracle certified professional  java se 6 programmer 3

Ejemplo:

Un objeto Dimension es declarado e inicializado con un "width" con valor 5 y un"height" con valor 10. Después, Dimension "b" es declarada y asignada el valor de"b". Solo hay un objeto Dimension, el que ambas variables "a" y "b" hacenreferencia. Finalmente, la propiedad height es cambiada usando la referencia "b".La salida es:%java ReferenceTesta.height = 10a.height = 30 after change to b

De esta salida, podemos sacar una conclusión que ambas variables serefieren a la misma instancia del objeto Dimension. Cuando hacemos uncambio en "b", el cambio también se reflejara para "a". Una excepción a lamanera de asignar una referencia a objeto es String. Los objetos String soninmutables.Ejemplo:

La salida es:%java StringTesty String = Javay String = Java

Como se puede ver, aunque "y" hace referencia al mismo objeto que "x", cuandonosotros cambiamos x, no cambia "y". Para cualquier tipo de objeto, donde dosreferencias apuntan al mismo objeto, si una referencia es usada para cambiar elobjeto, ambas referencias verán los cambios ya que solo existe un objeto. Pero

Page 20: Oracle certified professional  java se 6 programmer 3

cada vez que hagamos cualquier cambio a un String, la VM actualizara la variablede referencia para referirse a otro objeto diferente. La razón por la que nopodemos decir seguro que se crea un objeto nuevo es porque hay un pool deString, que veremos más en profundidad en el Capítulo 6.

Necesitas entender que sucede cuando usas una variable de referencia Stringpara modificar un String: Un nuevo String es creado (o encuentra un String en el pool de String),

dejando el original String sin modificaciones. La referencia usada para modificar el String (hacer un nuevo String

modificando una copia del original) es entonces asignada al nuevo objetoString.

Así que cuando decimos

No cambias el objeto String original creado en la línea 1. Cuando la línea 2 seacaba, ambos "t" y "s" hacen referencia al mismo objeto String. Pero cuando lalínea 3 se ejecuta, se crea un nuevo objeto String.

3.1. Pasando referencias a objetoCuando pasamos una variable objeto a un método, debemos tener en cuentaque estamos pasando la referencia al objeto y no el objeto en sí. Recordarque una variable referencia contiene bits que representa la manera deobtener un objeto específico de la memoria Heap. Lo más importante quedebemos recordar es que no estamos enviando la variable de referenciaactual, sino más bien una copia de la variable de referencia.Una copia de una variable significa obtener una copia de los bits de la variable, asícuando pasemos una variable referencia, estaremos pasando una copia de losbits. En otras palabras, el llamador y el método llamado tiene idénticas copias dela referencia y ambos se refieren al mismo objeto de la Heap.Para el siguiente ejemplo, usaremos la clase Dimension del paquete java.awt:

Page 21: Oracle certified professional  java se 6 programmer 3

Cuando ejecutamos esta clase, podemos ver que el método modify() fue capaz demodificar el objeto original Dimension creado en la línea 4.C:\Java Projects\Reference>java ReferenceTestBefore modify() d.height = 10dim = 11After modify() d.height = 11

Fíjate cuando el objeto Dimension es pasado al método modify(), cualquier cambioque se produzca dentro del método se está realizando sobre el objeto cuyareferencia fue pasada. En el ejemplo anterior, ambas variables de referencia d ydim apuntan al mismo objeto.

¿Java utiliza semánticas paso por valor?Java es actualmente Paso Por Valor para todas las variables en ejecucióndentro de una sola VM. Paso por Valor significa pasar el valor de unavariable.Y esto significa, pasar la copia de la variable.NO hay diferencia si estas pasando primitivos o variables de referencia, siemprepasaras una copia de los bits de la variable. Así para una variable primitiva, túpasaras una copia de los bits que representan el valor. Por ejemplo, si tú pasasuna variable entera con el valor 3, tú estarás pasando una copia de los bits querepresentan al número 3. El método llamado entonces obtiene su propia copia delvalor para hacer con él lo que quiera.Y si estas pasando una variable referencia a objeto, estarás pasando una copia delos bits que representan la referencia a un objeto. Por ejemplo, en el siguientefragmento de código,

Reasignando g no reasignas f. Al final del método Bar() se han creado dos objetosFoo uno referenciado por la variable f y una referenciado por la variable local g.Debido a que el método doStuff() tiene una copia de la variable de referencia,tiene una manera de obtener el objeto original Foo, por ejemplo llamando almétodo setName(). Pero el método doStuff() no tiene manera de obtener lavariable de referencia f. Así que doStuff() puede cambiar el valor del objeto al quehace referencia f, pero no puede cambiar el contenido actual (patrón de bits) de f.En otras palabras, doStuff() puede cambiar el estado del objeto al que hacereferencia la variable, pero no cambiar la referencia de f para que apunte a unobjeto diferente.

Page 22: Oracle certified professional  java se 6 programmer 3

3.2. Pasando variables primitivasObservar que sucede cuando una variable primitiva es pasada a un método:

En este simpleprograma, la variable a es pasada a un método llamado modify(), que incrementala variable sumándole uno. La salida será algo parecido a esto:Before modify() a = 1number = 2After modify() a = 1

Fíjate como a no cambia después de haber pasado por el método, Recordar, loque se le pasa al método es una copia de a. Cuando una variable primitiva espasada a un método, es pasada por valor, que significa pasar la copia de los bitsde la variable.

El mundo de las variables ocultasEl efecto de Shadowing es ocultar la variable previamente declarada de tal maneraque parezca como si estuvieses utilizando la variable oculta, pero tú estarásusando la variable "shadowing". Tú puedes "ocultar" una variable declarando unavariable local con el mismo nombre, ya sea directamente o como parte de unargumento:

Page 23: Oracle certified professional  java se 6 programmer 3

El código anterior parece cambiar la variable de instancia "size" en el métodochangeIt(), pero aunque changeIt() tiene un parámetro llamado size, la variablelocal size es modificada mientras la variable de instancia size permaneceintocable. Ejecutando la clase obtendremos la salida:%java Foosize = 7size in changeIt is 207size after changelt is 7La cosa se pone más interesante cuando la variable oculta es una referencia aobjeto, en lugar de una primitiva:

La salida del código anterior es:f.myBar.barNum is 28myBar.barNum in changelt is 99myBar.barNum in changeIt is now 420f, myBar. barNum after changeIt is 99

Puedes ver que la variable "shadowing" (el parámetro local myBar en changeIt())puede afectar a la variable de instancia, porque el parámetro myBar recibe unareferencia al mismo objeto Bar. Pero cuando el local myBar es reasignado a unnuevo objeto Bar, el cual modificaremos usando el valor barNum, la variable deinstancia original de Foo no está modificada.

4. Objetivo de Certificación 1.3 - Array declaración, construcción einicialización

1.3 Desarrollar código que declare, inicialice y use tipos primitivos, enumerados,arrays y objetos como estáticos, de instancia y como variables locales. Además,usar identificadores legales para los nombres de variables.

Page 24: Oracle certified professional  java se 6 programmer 3

4.1. Declarando un arrayLos arrays se declaran indicando el tipo de elementos que contendrá, que puedeser un objeto o un primitivo, seguido de corchetes a la izquierda o a la derecha delidentificador. Declarando un array de primitivos

Declarando un array de referencias a objetos

Cuando se declara una referencia array, siempre se debe poner los corchetesjusto después de declarar el tipo, en lugar de después del identificador (nombre dela variable). Esto facilitara la lectura del código.También se pueden declarar un array multidimensional, que es simplemente unarray de arrays. Esto se puede hacer de la siguiente manera:

El segundo ejemplo que tenemos unos corchetes antes del identificador y otrodespués. Esto es perfectamente legal para el compilador, demostrando una vezmás el hecho de que aunque sea legal no significa que sea correcto.Nunca es legal incluir el tamaño del array en la declaración.

El código anterior no compilara. Recordar, la JVM no asigna espacio hasta que seinstancia al objeto array.

4.2. Construyendo un arrayConstruir un array significa crear el objeto array en la memoria Heap (donde viventodos los objetos) haciendo un "new" sobre el tipo array. El tamaño del array es elnúmero de elementos que el array contendrá.

Construcción Array UnidimensionalLa manera más sencilla de construir un array es usando la palabra "new" seguidodel tipo de array, con unos corchetes especificando cuantos elementos del tipocontendrá el array. Ejemplo de la construcción de un array de tipo int.

El anterior código coloca un nuevo objeto en la memoria Heap (un objeto arrayque contendrá cuatro elementos) donde cada elemento contendrá un int con elvalor por defecto 0). Lo que le diríamos al compilador es:"Crea un objeto array quecontendrá 4 enteros y asignarle la variable de referencia llamada testScores.

Page 25: Oracle certified professional  java se 6 programmer 3

También, estableceremos cada elemento entero a 0." La siguiente figura nosmuestra el array testScores en la memoria Heap, después de la construcción.

También se puede declarar y construir un array en una sola sentencia:

Esta única sentencia genera el mismo resultado que las dos sentencias que vimosanteriormente. Los arrays de tipo Objeto pueden ser declarados de la mismamanera.

Después de la sentencia anterior, no existen aún objetos Thread.

Recuerda, los arrays deben siempre indicar su tamaño a la hora de construirlos.La JVM necesita el tamaño para asignar el apropiado espacio en la memoria Heappara el nuevo objeto array. Nunca es legal hacer lo siguiente:

Así que no hacerlo y si tú lo ves en el examen ve directamente a la respuestaCompilation Failed!

Construcción Array MultidimensionalEl siguiente código declara y construye un array bidimensional de tipo entero:

Fíjate que solo los primeros corchetes llevan el tamaño. Esto es aceptable enJava, ya que la JVM solo necesita saber el tamaño del objeto asignado a lavariable myArray. La siguiente figura muestra un array multidimensional en lamemoria Heap.

Page 26: Oracle certified professional  java se 6 programmer 3

4.3. Inicializando un arrayLas "cosas" en el array son los elementos del array y pueden ser primitivos(2,x,false) o objetos referenciados por una variable de referencia en el array. Sitienes un array de objetos (al contrario que los primitivos, el array nocontiene los objetos, pero en cambio tiene una referencia al objeto.Los elementos individuales en un array pueden ser accedidos con un índicenumérico. El índice numérico siempre empieza en 0, así que para un array de 10elementos el índice que lo recorrería iría desde 0 a 9.Ejemplo:

Nosotros tenemos un objeto array en la memoria Heap, con tres referencias nullde tipo Animal, pero nosotros no tenemos ningún objeto Animal. El próximo pasoserá crear algún objeto Animal y asignárselo a alguna posición del array:

Este código coloca tres nuevos objetos Animal en la memoria Heap y los asigna alas tres posiciones en el array pets.

Un array bidimensional puede ser inicializado como veremos a continuación.

Page 27: Oracle certified professional  java se 6 programmer 3

Inicializando elementos en un bucleLos objetos array tienen una única variable pública, length que te da el número deelementos de un array. El valor del último índice es siempre uno menos que eltamaño. Por ejemplo, si el tamaño de un array es 4, el valor de índices va desde 0hasta 3. A menudo, tu veras inicializar elementos de array en un bucle comopodemos ver a continuación:

La variable length nos da el número de elementos de un array, pero no nos da elnúmero de elementos que han sido inicializados.

4.4. Declarando, construyendo e inicializando en una líneaPuedes usar dos diferentes sintaxis shortcuts de especificar array para inicializar yconstruir en una sola sentencia.1.- La primera se usa para declarar, crear e inicializar en una sola sentenciacomo la siguiente:

La línea dos en el anterior código hace 4 cosas: Declara una variable de referencia de tipo array entero llamado dots Crea un array entero con un tamaño de 3 Rellena el array con los valores 6,9 y 8 Asigna el nuevo objeto array a la variable de referencia dots

El tamaño está determinado por el número de comas entre las llaves. El siguientecódigo largo es funcionalmente equivalente al anterior:

Page 28: Oracle certified professional  java se 6 programmer 3

Con referencias de objetos trabaja de la misma forma que con primitivas.

El anterior código crea un array Dog, referenciado por la variable myDogs, contamaño 3. Le asigna un objeto Dog creado previamente (asignado a la variablepuppy) al primer elemento del array. También crea dos nuevos objetos y losasigna a los dos elementos restantes. La siguiente figura muestra el resultado.

También podemos usar la sintaxis corta con arrays multidimensionalescomo los siguientes:

El anterior código crea un total de 4 objetos en la memoria Heap. Primero, unarray de enteros es construido (el objeto que será asignado a la variable dereferencia scores). El array scores tiene un tamaño de 3, derivado del número decomas entre las llaves exteriores. Cada uno de los tres elementos en el arrayscores es una variable de referencia a un array entero, así que los tres enterosarrays son construidos y asignados a los tres elementos en el array scores.El tamaño de cada uno de los elementos es derivado del número de comas quehay entre las llaves internas. Por ejemplo, el primer array tiene tamaño 4, elsegundo 2, y el tercero 2. Finalmente los tres elementos del array scores soninicializados con los valores que tienen entre llaves.El siguiente código muestra los valores de algunos de los elementos en este arraybidimensional:

Page 29: Oracle certified professional  java se 6 programmer 3

4.5. Construyendo e inicializando un array anónimo2.- El segundo shortcut es denominado "anónima creación de array" y puedeser usada para construir e inicializar un array, y entonces asignar el array auna variable de referencia array declarada previamente.

El anterior código crea un nuevo array entero con tres elementos, inicializa loselementos con los valores 4,7 y 2 y entonces asigna el nuevo array a la variablede referencia testScores declarada previamente. Nosotros la llamamos creaciónanónima de array porque no necesitamos asignar el nuevo array a nada. Ejemplo :

4.6. Arrays de primitivosEjemplo:

4.7. Arrays de referencias a objetosSi el tipo que se declara en un array es una clase, puedes poner objetos decualquier subclase del tipo declarado en el array. Por ejemplo, si Subaru es unasubclase de Car, tú puedes poner tanto objetos Subaru como objetos Car dentrodel array de tipo Car, como podemos ver a continuación:

Page 30: Oracle certified professional  java se 6 programmer 3

Los elementos en un array Car son nada más que variables de referencia de Car.Así que cualquier cosa que pueda ser asignada a una variable de referenciapuede ser legalmente asignada a un array de tipo Car.Si el array es declarado como tipo una interfaz, los elementos del array puedenreferirse a cualquier instancia de cualquier clase que implemente la interfazdeclarada. El siguiente ejemplo nos muestra un array donde el tipo es una interfaz:

La conclusión es: Cualquier objeto que pase el test "IS-A" para el tipodeclarado en el array, puede ser asignado a un elementos del array.

4.8. Asignaciones de referencias de array para Arrays UnidimensionalesPara el examen, necesitas saber asignaciones legales e ilegales para variables dereferencia array. El siguiente código nos muestra asignaciones legales e ilegalesde asignaciones para arrays primitivos:

Page 31: Oracle certified professional  java se 6 programmer 3

Es difícil asumir que aunque una variable de tipo byte, short o char puede serexplícitamente promocionada y asignada a un entero, un array de cualquiera deestos tipos no se puede asignar a un array de enteros.Los arrays que contienen referencias a objetos, al contrario que los primitivos, noson tan restrictivos. Ya que tú puedes poner un objeto Honda en un array de Car(ya que Honda extiende de Car), veamos lo en un ejemplo:

Aplicar el test IS-A ayuda a ver si es legal o ilegal la asignación.Las reglas para arrays donde es tipo es una interfaz son iguales que con las clase.Un array declarado con un tipo interfaz puede referenciar un array de cualquiertipo que implemente la interfaz. Recordar, cualquier objeto de una clase queimplemente una interfaz en particular pasara el test IS-A (instanceof) paraesta interfaz. Por ejemplo, if Box implementa Foldable, lo siguiente serialegal:

4.9. Asignaciones de referencias de array para Arrays MultidimensionalesCuando asignas un array a una referencia array previamente declarada, el arrayque estas asignando debe tener la misma dimensión que la referencia a la que laestas asignando. Por ejemplo, un array bidimensional de arrays de enteros nopuede ser asignado a una referencia de array unidimensional de tipo entero.

Page 32: Oracle certified professional  java se 6 programmer 3

Prestar atención a las asignaciones de arrays que tengan diferentesdimensiones. Es posible que, por ejemplo, se pregunte si es legal una asignaruna array de enteros al primer elemento en un array de arrays de enteros, comopodemos ver a continuación:

La siguiente imagen nos muestra ejemplos de asignaciones legales e ilegales dereferencia a un array:

4.10. Bloques de inicializaciónLos bloques de inicialización se ejecutan cuando la clase es cargada por primeravez (un bloque de inicialización estático) o cuando se crea una instancia. Ejemplo:

Un bloque de inicialización estático se ejecuta una vez, cuando la clase escargada por primera vez. Una instancia ejecuta el bloque de inicialización una vez,

Page 33: Oracle certified professional  java se 6 programmer 3

cada vez que una nueva instancia es creada.En un constructor el bloque de código de inicialización se ejecuta inmediatamentedespués de la llamada al constructor super().Puedes tener muchos bloques de inicialización en una clase.A diferencia de los métodos o los constructores, el orden en que aparecen losbloques de inicialización en una clase. Si hay más de un bloque de inicializaciónse ejecutara en el orden de aparición en el fichero de la clase. Ejemplo:

Para saber la salida debemos recordar las reglas: Los Bloques de inicialización se ejecutan en el orden en el que aparecen. Los bloques de inicialización estáticos se ejecutan una vez, cuando la clase es

cargada por primera vez. Los bloques de inicialización de instancia se ejecutan cada vez que se crea

una instancia. Los bloques de inicialización de instancia se ejecutan después de la llamada al

constructor super().

Teniendo las reglas en cuenta, la salida siguiente tendría sentido.1st static init2nd static init1st instance init2nd instance initno-arg const1st instance init2nd instance init1-arg const

Como podemos ver los bloques de inicialización de instancia se ejecutaron dosveces cada uno. Los bloques de inicialización de instancia a menudo son usadospara poner el código que queremos que todos los constructores de una clasecompartan. De esta forma el código no tiene que ser duplicado a través de losconstructores.Un error en tu bloque de inicialización estático, la JVM puede lanzar unaExceptionInIninitalizationError. Ejemplo:

Page 34: Oracle certified professional  java se 6 programmer 3

Produce la siguiente salida:Exception in thread "main" java.lang.ExceptionInInitializerErrorCaused by: java.lang.ArrayIndexOutOfBoundsException: 4at InitError.<clinit>(InitError.java:3)

5. Objetivo de Certificación 3.1 - Usando clases de envoltura y Boxing3.1 Desarrollar código que use las clases de envoltura de primitivos (tales comoBoolean, Character, Double, Integer, etc), y/o autoboxing & unboxing. Discutir lasdiferencias entre las clases String, StringBuilder y StringBuffer.

5.1. Descripción general de clases de envolturaHay una clase de envoltura para cada primitivo en Java. Por ejemplo, la clase deenvoltura para int es Integer, la clase Float es de float y así todas. A excepción deint que es Integer y char que es Character. La siguiente tabla muestra la lista declases de envoltura en la API de Java.

Primitivo Clase deenvoltura

ArgumentosConstructor boolean Boolean boolean or

Stringbyte Byte byte or Stringchar Character chardouble Double double or Stringfloat Float float, double or Stringint Integer int or Stringlong Long long or Stringshort Short short or String

5.2. Creando objetos de envolturaPara el examen necesitas entender los tres enfoques más comunes para lacreación de objetos de envoltura. Algunos enfoques toman un String enrepresentación de un primitivo como argumento. Estos que toman un Stringlanzan NumberFormatException si el String proporcionado no puede serparseado al apropiado primitivo. Por ejemplo, "two" no puede ser parseado a"2". Los objetos de envoltura son inmutables. Una vez que hayan obtenidoun valor es imposible modificarlo.

Page 35: Oracle certified professional  java se 6 programmer 3

5.3. Los constructores de envolturaTodas las clases de envoltura excepto Character proporcionan dos constructores:un que toma un valor primitivo del tipo que está siendo construido y otro que tomaun String en representación del tipo que está siendo construido, Por ejemplo:

La clase Character proporciona solo un constructor que toma como argumento unchar, por ejemplo:

El constructor de la clase de envoltura Boolean toma un valor booleano "true" o"false" o un String case-insensitive con el valor "true" o "false". Antes de Java 5,un objeto booleano no podía ser usado como expresión en un test booleano,por ejemplo.

A partir de Java 5, un objeto Boolean puede ser usado en un test booleano, ya queel compilador automáticamente convertirse el Boolean a boolean.

5.4. Los métodos valueOf()Los dos métodos estáticos valueOf() proporcionados en la mayoría de clases deenvoltura dan otro enfoque para la creación de objetos de envoltura. Ambosmétodos toman un String en representación del apropiado tipo de primitivo comoprimer argumento, el segundo método toma un argumento adicional, int radix, queindica en que base se representado el primer argumento (por ejemplo binario,octal o decimal), veamos un ejemplo a continuación:

5.5. Usando utilidades de conversión en clases de envolturaLos siguientes métodos son los más usados comúnmente y son los queprobablemente más veas en el examen.

xxxValue()Cuando necesitas convertir el valor numérico de una clase envoltura a un tipoprimitivo use uno de los muchos métodos xxxValue(). Todos los métodos de estafamilia no llevan argumentos. Hay 36 métodos xxxValue(). Cada una de las seis

Page 36: Oracle certified professional  java se 6 programmer 3

clases de envoltura tiene 6 métodos, así que cualquier numérico de una clase deenvoltura puede ser convertido a cualquier tipo numérico primitivo, por ejemplo:

parseXxx() y valueOf()Los seis métodos parseXxx() están estrechamente relacionados con los métodosvalueOf() que existen en todos los números de las clases de envoltura. Ambosmétodos toman un String como argumento, lanzan unNumberFormatException si el argumento String no está bien formado, ypuede convertir objetos String de diferentes bases, cuando el subyacente tipoprimitivo es cualquiera de los cuatro tipos de enteros.La diferencia entre los métodos es: parseXxx devuelve el primitivo nombrado. valueOf() devuelve un nuevo objeto de la clase de envoltura del tipo que invoca

al método.Aquí algunos ejemplos de estos métodos en acción:

Los próximos ejemplos involucran el uso del argumento radix (en este casobinario):

toString()La clase Object tiene un método toString(). Las otras clases Java heredan de laclase Object, entonces todas las clases tienen un método toString(). Elmétodo toString() te permite obtener una representación significativa de un objeto.Ejemplo:

Page 37: Oracle certified professional  java se 6 programmer 3

Todas las clases de envolturas numéricas proporcionan un métodosobrecargado toString() que toma un numérico primitivo del tipo apropiado(Doubel.toString() toma un double, Long.toString() toma un long, y asísucesivamente) y devuelve un String:

Integer y Long proporcionan un tercer método toString(). Es estático, su primerargumento es el primitivo y su segundo argumento es la base. La base le dice almétodo que tome el primer argumento y lo convierta a la base proporcionada (labase por defecto es 10), entonces devuelve el resultado como un String, porejemplo:

toXxxString()(Binario, Hexadecimal, Octal)Las clases de envoltura Integer y Long te permiten convertir un número en base10 a otras bases. Estos métodos de conversión, toXxxString(), toman un int o long,y devuelven una representación del número convertido, por ejemplo:

La siguiente tabla es la mejor manera para prepararse esta sección para elexamen.~Método (s->static, n->NFE exception ~Boolean ~Byte Character Double Float Integer long Short

byteValue x x x x x xdoubleValue x x x x x xfloatValue x x x x x xintValue x x x x x xlongValue x x x x x xshortValue x x x x x xparseXxx s,n x x x x x xparseXxx (base) s,n x x x xvalueOf s,n s x x x x x xvalueOf (base) s,n x x x xtoString x x x x x x xtoString(primitivo) s x x x x x x xtoString(primitivo,base) s x x

Page 38: Oracle certified professional  java se 6 programmer 3

En resumen:primitivo xxxValue() - Convierte una clase de envoltura en un primitivoprimitivo parseXxx(String) - Convierte un String a un primitivoClase Envoltura valueOf(String) - Convierte un String a una clase de envoltura

AutoboxingEs una nueva caracteristica de Java 5 conocida como: autoboxing, auto-unboxing,boxing y unboxing. Utilizaremos los términos boxing y unboxing. Boxing yunboxing hacen uso de las clases de envoltura más convenientemente.Antiguamente en Java, antes de Java 5, tú debías hacer lo siguiente:

Ahora podemos decir lo siguiente, para obtener la misma funcionalidad:

Ambos ejemplos producen la misma salida: y = 568Es seguro, se ve como se cambia el valor de y de 567 a 568. lo que sucede esque un segundo objeto de clase de envoltura se creó y su valor fue puesto a 568.Vamos a probar lo siguiente:

El código anterior produce la salida:true567 568false

Así que cuando el compilador llega a la línea y++, tiene que sustituirlo por algocomo esto:

Boxing, == y equals()El método equals() determina si dos instancias de una clase dada sonequivalentes de manera significativa. Ejemplo :

Page 39: Oracle certified professional  java se 6 programmer 3

Produce la siguiente salida:different objectsmeaningfully equal

Este ejemplo produce la salida:same objectmeaningfully equal

Dos instancias de la siguiente lista de objetos de clase de envoltura siempre serániguales cuando sus valores primitivos sean los mismos:

Boolean Byte Character from \u0000 to \u007f (7f is 127 in decimal) Short and Integer from -128 to 127

NOTA: Cuando usamos == para comparar un primitivo a una clase de envoltura, laclase de envoltura será unwraped y la comparación será primitivo a primitivo.

5.6. Donde puede ser usado BoxingEl siguiente código nos muestra una forma legal de usar boxing:

6. Objetivo de Certificación 1.5 y 5.4 - Sobrecarga1.5 Desarrollar código que declare métodos estáticos y no estáticos y usar paralos métodos nombres que se ajusten al estándar de nombres de JavaBeans.Desarrollar código que declare y use una lista de argumentos variables. Dado un

Page 40: Oracle certified professional  java se 6 programmer 3

código de ejemplo, determinar si un método esta correctamente sobrescribiendo osobrecargando a otro método e identificar valores legales de devolución (return,incluyendo covariantes de return) para el método.5.4 Dado un escenario, desarrollar código que declare y/o invoque métodossobrescritos y sobrecargados y código que declare y/o invoque constructores de lasuperclase, sobrescritos o sobrecargados.

6.1. Sobrecarga - Método concordanciaTres factores que pueden hacer la sobrecarga un poco complicada.

Ampliar (Widening) Autoboxing Var-args

Cuando una clase tiene métodos sobrecargados, uno de los trabajos delcompilador es determinar cual método usar cada vez que encuentre unainvocación al método sobrecargado:

El código producirá la salida siguiente:int int long double

Las llamadas que usan byte y short como argumentos son implícitamenteampliadas (widened) para encajar con la versión del método go() que toma unentero. Por supuesto, la llamada que usa el argumento long usa la versión de go()que toma un long. Y finalmente, la llamada que usa float es encajada con elmétodo que tomaba double.En todos los casos, cuando no se encuentra una exacta conexión, la JVM usa elmétodo con el argumento menor que sea más amplio que el parámetro.

6.2. Sobrecarga - Boxing y Var-argsAhora tomaremos nuestro último ejemplo y le añadiremos boxing:

Page 41: Oracle certified professional  java se 6 programmer 3

Como hemos visto anteriormente, si la única versión del método go() fuese unaque toma un Integer, entonces La capacidad de boxing de Java5 permitiría lainvocación de go(). Del mismo modo, si solo existiese la versión long el compiladorlo usaría para hacer la invocación. El compilador elige ampliar antes que realizarboxing, así que la salida sería: long

Intenta predecir la salida del siguiente código:

Como probablemente adivinaste, la salida es: int, intYa que, una vez más, aunque cada invocación requiera algún orden deconversión, el compilador elegirá el estilo antiguo antes de elegir el nuevo. Hastala fecha hemos visto que:

Ampliación (widening) se antepone a boxing. Ampliación (widening) se antepone a var-args.

A continuación veremos quién se antepone a quien, si el boxing a var-args oviceversa:

La salida será: Byte, Byte

Page 42: Oracle certified professional  java se 6 programmer 3

6.3. Ampliación (widening) de variables de referenciaHemos visto que es legal ampliar un tipo primitivo. Vamos a pensar de nuevo en laasignación polimórfica para ver si se puede hacer ampliación de una variable dereferencia y si es así que significaría.

En el mismo sentido, una invocación debe ser:

El método go() necesita un Animal y Dog3 IS-A Animal. Así que, en este caso, elcompilador ampliara la referencia Dog3 a una Animal y la invocación ir bien. Laclave aquí es que la ampliación depende de la herencia, en otras palabras el testIS-A. Debido a esto, no es legal ampliar de una clase de envoltura a otra. Porejemplo, no es correcto decir que Short IS-A Integer

6.4. Sobrecarga combinando Widening y BoxingEn este caso el compilador tendrá que ampliar y entonces hacer autobox alparámetro.

Esto ya es mucho para el compilador:WidenAndBox.java:6: go(java.lang.Long) in WidenAndBox cannot beapplied to (byte)

Es posible para el compilador realizar una operación boxing seguida por unaoperación de ampliación para conseguir encajar una invocación a un método.

Page 43: Oracle certified professional  java se 6 programmer 3

Esto compila y produce la salida: 5.Lo siguiente es lo que sucede cuando el compilador llega a la línea que invoca almétodo go().

Al byte b se le realiza una operación de boxing a Byte. La referencia Byte se amplía a Object (Byte extiende de Object). El método go()obtiene una referencia Object que actualmente se refiere a

un Byte. El método go() hace un casting de la referencia Object a una referencia

Byte (recordar, nunca hay un objeto Object solo un objeto de tipo Byte). El método go() pinta el valor del Byte.

6.5. Sobrecarga en combinación con var-argsEjemplo:

Esto compila y produce: long... Integer...

Las reglas para sobrecargar método usando ampliación, boxing y var-args Ampliación de primitivos usa el método con el tamaño más pequeño de

argumento posible. Usar individualmente, boxing y var-args es compatible con las sobrecargas. No se puede ampliar de una clase de envoltura a otra (IS-A falla). No puedes hacer una ampliación y después box (un int no puede volver a

Long).

Page 44: Oracle certified professional  java se 6 programmer 3

Si puedes hacer una operación de box y después una ampliación (un int puedevolver a Object, vía Integer).

Puedes combinar var-args con ampliación y boxing.

Hay más aspectos de sobrecarga, pero lo veremos con mayor profundidad en elcapítulo 7.

7. Objetivo de Certificación 7.4 - Garbage Collection7.1 Dado un código de ejemplo, reconocer los puntos en los cuales un objeto eselegido para garbage collection y determinar que es lo que está garantizado por elsistema garbage collection. Reconocer las características de System.gc yfinalización.

7.2. Descripción del garbage collector de JavaLa memoria Heap es la parte de la memoria donde se almacenan los objetos Javavivos y es la única parte de la memoria que está implicada en el proceso degarbage collection. La función de garbage collector gira en torno a asegurar que laHeap tenga suficiente espacio libre. La función de garbage collector es aeliminar cualquier objeto que no es accesible para el programa Java que esteen ejecución.

7.3. Cuando se ejecuta el garbage collectorEl garbage collector está bajo el control de la JVM. La JVM decide cuando ejecutarel garbage collector. Desde dentro de tu programa puedes pedir a la JVM queejecute el garbage collector, pero no hay garantías de que la JVM lo vaya acumplir. La JVM lo ejecutara normalmente cuando vea que la memoria tiene unabaja ejecución.

7.4. Escribir código que marque explícitamente objetos elegibles paraCollectionVamos a mostrar cómo hacer objetos elegibles para garbage collection usandocódigo. También examinaremos la forma de intentar forzar garbage collection si esnecesario y cómo podemos realizar limpieza adicional en objetos antes de sereliminados de la memoria.

Anulando una referenciaLa primera forma de eliminar una referencia a un objeto es poniéndole a lavariable de referencia que se refiere al objeto null. Fíjate en el siguiente código:

Page 45: Oracle certified professional  java se 6 programmer 3

El objeto StringBuffer con el valor Hello es asignado a la variable de referencia sben la tercera línea. Para hacer al objeto elegible por GC, pondremos la variable dereferencia a null, lo cual elimina la única referencia que existía al objetoStringBuffer. Des la línea 6 el objeto ya es elegible para GC.

Reasignando una variable de referenciaTambien podemos hacer que la variable de referencia de un objeto pase areferirse a otro objeto. Observemos el siguiente código:

Los objetos que son creados dentro de los métodos también necesitan serconsiderados. Cuando un método es invocado, cualquier variable local creadaexiste solo durante la duración del método. Una vez que el método hayaterminado, los objetos creados en el método son elegibles para GC. Hay unaexcepción obvia, sin embargo. Si un objeto es devuelto desde el método, sureferencia debe ser asignada a una variable de referencia en el método que lollamo, por lo tanto no será elegible para GC. Observemos el siguiente código:

Page 46: Oracle certified professional  java se 6 programmer 3

En el ejemplo anterior, creamos un método llamado getDate() que devolvía unobjeto Date. Este método crea dos objetos: un Date y un StringBuffer conteniendola información de la fecha. Desde que el método devuelve el objeto Date, no seráelegible para GC incluso después de que el método se haya completado. El objetoStringBuffer será elegible, incluso aunque le indicásemos explícitamente a lavariable now el valor null.

Aislando una referenciaHay otra manera de hacer a los objetos elegibles para GC incluso teniendo aúnreferencias validas. Examinemos el siguiente código:

Los tres objetos Island tienen variables de instancia refiriéndose entres sí, perosus vínculos son el mundo exterior son nulos. Estos tres objetos son elegiblespara GC.

Forzando Garbage CollectionLas rutinas de Garbage Collection que Java proporciona son miembros de la claseRuntime. La clase Runtime es una clase especial que tiene un solo objeto(singleton) para cada programa principal. El objeto Runtime proporciona un

Page 47: Oracle certified professional  java se 6 programmer 3

mecanismo para comunicarse directamente con la JVM. Para obtener la instanciade Runtime, tu puedes usar el método Runtime.getRuntime(), el cual devuelve elsingleton. Una vez que tengas el singleton puedes invocar al garbage collectorusando el método gc(). Alternativamente, puedes llamar el mismo método en laclase System, que tienen métodos estáticos que pueden hacer el trabajo deobtener el singleton por ti. La manera más fácil de preguntar al GC es:System.gc();

Teóricamente, después de llamar a System.gc(), tendremos la mayor cantidad dememoria libre posible. Decimos teóricamente porque esta rutina no siempretrabaja de esta forma. Primero, tu JVM podrá no tener implementado esta rutina.Segundo, otro hilo podría ocupar gran cantidad de memoria después de haberlanzado el GC.El siguiente ejemplo nos permite ver la cantidad de espacio total que tiene dememoria la JVM disponible y cuanto espacio libre tiene. Si entonces creamos10000 objetos Date. Después de esto, nos dirá cuanta memoria nos queda yentonces llamaremos al garbage collector.

El resultado final de la memoria libre nos indicara si se ha ejecutado el GC.Veamos el código:

Ahora ejecutemos el programa y veamos su salida:Total JVM memory: 1048568Before Memory = 703008After Memory = 458048After GC Memory = 818272//

La JVM decidió hacer al final el GC de los objetos elegibles. La única cosa quepuedes garantizar es que si se está ejecutando la memoria muy lenta, el GCse ejecutara antes de lanzar un OutOfMemoryException

Page 48: Oracle certified professional  java se 6 programmer 3

7.6. Limpiando antes de Garbage Collector (método finalize())Java proporciona un mecanismo para ejecutar algún código justo antes de que elobjeto sea eliminado por el GC. Este código está localizado en un método llamadofinalize() que todas las clases heredan de la clase Object. Cualquier código que tupongas en el método finalize() sobrescrito no se garantiza su ejecución. Por lotanto no pongas código esencial en el método finalize. De hecho, recomendamosque por lo general no se sobrescribe el método finalize().

Guía para el Examen 3.1Presta una atención especial a los errores en bloques de código. Podríasencontrártelos en bucles como switch, try-catch, for, do y while.

Guía para el Examen 3.2Automático es otro término para las variables locales. No significa que a unavariable automática se le asigne automáticamente un valor. Lo verdadero seria locontrario. Una variable automática debe tener asignada un valor en el código si noel compilador se quejara.

Guía para el Examen 3.3Piense cuantos objetos habrá en la memoria heap después de ejecutar unasentencia o bloque de código. En el examen esperaran que tu lo sepas, porejemplo en el código que hemos visto anteriormente debemos saber que solo segenera un objeto. El objeto único referenciado por threads contendrá cincovariables de referencia Thread, pero no cinco objetos Thread que tienen que sercreados o asignados a estas referencias.

Guía para el Examen 3.4Tu puedes ver las palabras "construir", "crear" e "instanciar" utilizadasindistintamente. Todas significan, "Un objeto es construido en la memoria heap."Esto también implica que el constructor de objetos se ejecute, como el resultadode crear/construir/instanciar. Se puede decir con certeza, por ejemplo, quecualquier código que use la palabra "new" causara la ejecución del constructor dela clase y de todos los constructores de la superclase.

Guía para el Examen 3.5Busque código que intente acceder fuera del rango de un array. Por ejemplo, si unarray tiene tres elementos, intentando acceder al elemento [3] provocara unaexcepción ArrayIndexOutOfBoundsException, porque en un array de treselementos, el indice de valores legal seria 0,1 y 2. También debes de estar atentoal uso de un número negativo como indice de un array. Los siguientes ejemplosson accesos legales e ilegales. Asegúrate de reconocer que esto provocaexcepciones en tiempo de ejecución y no errores de compilación.Casi todas las preguntas de un examen ponen como opción posible las respuestas"error en tiempo de ejecución" y "error de compilación".

Page 49: Oracle certified professional  java se 6 programmer 3

Esto puede ser difícil de encontrar en un bucle complejo. Pero hay es donde masproblemas de indices de array se producen en las preguntas del examen.

Guía para el Examen 3.6Recordar que no especificas un tamaño cuando usas la sintaxis de creaciónanonima de array- El tamaño es derivado del número de comas (,) entre las llaves.Esta atento a preguntas del examen que pongan algo parecido a lo siguiente.

Guía para el Examen 3.7Las asignaciones de un array de una subclase, no pueden ser asignados a unarray cuyo tipo es la superclase. Por ejemplo, siguiendo con el ejemplo de Car ySubaru. Un array de Car no puede ser asignado a un array de Subaru. Un Car nonecesariamente tiene que ser Subaru. Recuerda que el test IS-A se puede hacerusando el operador instanceof.

Guía para el Examen 3.8Por convenio, los bloques de inicialización normalmente aparecen cerca de laparte de arriba del fichero de una clase, alrededor de los constructores. A menudo,this is the SCJP exam we're talking about. Don't be surprised if you find an initblock tucked in between a couple of methods, looking for all the world like acompiler error waiting to happen!

Guía para el Examen 3.9Recordar, variables de referencia cuyo tipo es una clase de envoltura pueden sernull. Esto significa que tienes que estar atento al código que parece estar haciendooperaciones primitivas seguras, pero que podrían lanzar un NullPointerException.

Page 50: Oracle certified professional  java se 6 programmer 3

Este código compila bien, pero la JVM lanza un NullPointerException cuandointente invocar doStuff(x), porque x no esta referenciado a ningún objeto Integer,así que no hay valor para realizar unbox.

Guía para el Examen 3.10Es tentador pensar que podriamos ser capaces de ampliaruna clase de envolturaInteger a otra Long, pero como veremos a continuación el siguiente código nocompilara:

Recuerda, ninguna de las clases de envoltura sera ampliada de una a otra. Bytesno se puede ampliar a Shorts, Shorts no se puede ampliar a Longs ...etc.