You are on page 1of 240

Tutorial para el Examen de certificacion: SCJP 1.

2
Traduccin del tutorial de Marcus Green.

RuGI Isaac Ruiz Guerra rugi@javahispano.org

javaHispano Tu lenguaje, tu comunidad. Versin Julio del 2003.

Tutorial para el examen de certificacin: SCJP 1.2

El presente documento es una traduccin/adaptacin del tutorial de Marcus Green correspondiente a la versin de diciembre del 2002. Dicho tutorial cubre los objetivos correspondientes al examen SCJP 1.2. La mayor parte de este documento cubre tambien los objetivos para la versin 1.4 nicamente se deben pasar por alto las secciones 8 y 11, y agregar el tema de Aserciones. Esta traduccin se realiz con la colaboracin de: Nombre: Isaac Ruiz Guerra Joslyn Flores Romero Francisco Fernndez Miser Alberto Molpeceres Seccin: 1, 2, 3, 4, 6, 8, 9, 10 7 5 11

Puedes hacer cualquier comentario sobre la traduccin a rugi@javahispano.org La direccin del tutorial de Marcus Green: http://www.jchq.net/certkey/index.htm Un artculo de Emili Miedes de Elas sobre Aserciones: http://www.javahispano.org/articles.article.action?id=57 Este documento forma parte del proyecto Examen de Certificacin: http://www.javahispano.org/text.viewer.action?file=proyectos

Copyright (c) 2003,Isaac Ruiz Guerra. Este documento puede ser distribuido solo bajo los trminos y condiciones de la licencia de Documentacin de javaHispano v1.0 o posterior (la ltima versin se encuentra en http://www.javahispano.org/licencias/).

javaHispano. Tu comunidad, tu lenguaje.

Seccin 1. Declaracin y control de Acceso ......................7

Objetivo 1........................................................................................................................ 7 Arreglos................................................................................................................... 7 Declaracin sin asignacin. ........................................................................................ 7 Creacin y Declaracin Simultanea............................................................................ 8 Arreglos Java VS Arreglos C/C++ . .................................................................... 8 Los arreglos conocen su tamao. ........................................................................... 9 Arreglos Java VS Arreglos VB............................................................................ 9 Combinar declaracin con inicializacin.................................................................. 10 Objetivo 2...................................................................................................................... 15 Comparando las clases de C++/VB con las de Java. ................................................ 15 El rol de las clases en Java........................................................................................ 15 La clase ms sencilla................................................................................................. 16 Creando una clase sencilla- HelloWorld................................................................... 16 La magia del nombre main ....................................................................................... 16 Creando una instancia de una Clase.......................................................................... 17 Creando Mtodos. ..................................................................................................... 18 Variables Automticas .............................................................................................. 19 Modificadores y Encapsulamiento............................................................................ 20 Usando modificadores en combinacin .................................................................... 26 Objetivo 3...................................................................................................................... 35 Nota de este objetivo................................................................................................. 35 Qu es un constructor? ............................................................................................ 35 Cundo proporciona Java el constructor predefinido?............................................ 35 El prototipo del constructor predefinido ................................................................... 37 Objetivo 4...................................................................................................................... 43 Nota de este objetivo................................................................................................. 43 Mtodos en la misma clase ....................................................................................... 43 Mtodos en una subclase. ......................................................................................... 44
Seccin 2. Control de Flujo y Manejo de Excepciones. ...........47

Objetivo 1...................................................................................................................... 47 La sentencia if/else.................................................................................................... 47 La Sentencia switch................................................................................................... 48 Argumentos validos para las sentencias if y switch. ................................................. 49 El operador ternario ?................................................................................................ 49 Objetivo 2...................................................................................................................... 55 La sentencia for......................................................................................................... 55 Los ciclos while y do, nada inesperado................................................................. 56 La sentencia goto, ciencia o religin? ..................................................................... 57 Break y Continue ...................................................................................................... 57 Saltar a una Etiqueta. ................................................................................................ 58 Objetivo 3...................................................................................................................... 64 Comparando con Visual Basic y C/C++................................................................... 64 La Clusula finally .................................................................................................... 65 Sobrescribiendo mtodos que lanzan excepciones ................................................... 66

Tutorial para el examen de certificacin: SCJP 1.2


Seccin 3. Recolector de basura Garbage Collector- ............72

Objetivo 1...................................................................................................................... 72 Por qu querras utilizar el recolector de basura? ................................................... 72 Java y el recolector de basura. .................................................................................. 72
Seccin 4. Fundamentos del lenguaje. ...........................76

Objetivo 1...................................................................................................................... 76 Nota sobre este objetivo............................................................................................ 76 La sentencia package ................................................................................................ 76 La sentencia import ............................................................................................... 77 Clases y la declaracin de clases internas................................................................. 77 Clases internas declaradas dentro de mtodos .......................................................... 79 Visibilidad de campos para clases definidas dentro de un mtodo........................... 80 Creando una interface ............................................................................................... 81 Objetivo 2...................................................................................................................... 85 Objetivo 3...................................................................................................................... 87 Objetivo 4...................................................................................................................... 90 Variables ................................................................................................................... 90 Arreglos..................................................................................................................... 91 Objetivo 5...................................................................................................................... 95 Tamao de los tipos primitivos enteros .................................................................... 95 Declarando literales enteros...................................................................................... 95 Tamao de los tipos primitivos de coma flotante ..................................................... 96 Indicando tipos de datos con un literal sufijo ........................................................... 97 Los tipos boolean y char........................................................................................... 97 Declarando literales String ................................................................................... 99
Seccin 5. Operadores y Asignaciones ..........................102

Objetivo 1.................................................................................................................... 102 El operador instanceof ....................................................................................... 102 El operador + .......................................................................................................... 103 Asignando variables primitivas de tipos diferentes ................................................ 104 Asignando referencias de objetos de diferentes tipos. ............................................ 105 Operadores de desplazamiento de bits.................................................................... 106 Operadores de desplazamiento con signo << y >> ................................................. 107 Desplazamiento sin signo a la derecha >>>............................................................ 108 Applet BitShift ........................................................................................................ 108 Objetivo 2.................................................................................................................... 113 Diferencia entre el mtodo equals y el operador = = .............................................. 113 Usando el mtodo equals con Strings ..................................................................... 113 Usando el mtodo equals con la Clase Boolean ..................................................... 114 Usando el mtodo equals con objetos..................................................................... 115 Objetivo 3.................................................................................................................... 119 El efecto corto circuito con los operadores lgicos. ............................................... 119 Operadores a nivel de bits....................................................................................... 120 Pensando en binario ................................................................................................ 120 Objetivo 4.................................................................................................................... 124 Nota sobre este objetivo.......................................................................................... 124 Referencias de Objetos como parmetros de mtodos. .......................................... 124 4

javaHispano. Tu comunidad, tu lenguaje. Primitivas como parmetros de mtodos ................................................................ 125


Seccin 6. Sobrecarga, sobreescritura, tipos en tiempo de ejecucin y orientacin a objetos .............................128

Objetivo 1) .................................................................................................................. 128 Relaciones es un y tiene un.............................................................................. 128 Encapsulamiento ..................................................................................................... 128 Tipos en Tiempo de ejecucin ................................................................................ 130 Objetivo 2) .................................................................................................................. 135 Comentario sobre el objetivo .................................................................................. 135 Sobrecarga de mtodos ........................................................................................... 135 Sobrescritura de mtodos....................................................................................... 136 Invocando constructores de clases base.................................................................. 137 Invocando constructores con this() ..................................................................... 138 El constructor y la jerarqua de clases..................................................................... 139 Objetivo 3) .................................................................................................................. 146 Nota sobre este objetivo.......................................................................................... 146 Instanciando una clase ............................................................................................ 146 Clases internas ........................................................................................................ 146 Clases Anidadas de nivel Superior (Top Level) ..................................................... 147 Clases Miembro ...................................................................................................... 147 Clases creadas dentro de mtodos........................................................................... 148 Clases annimas...................................................................................................... 148
Seccin 7. Threads ............................................152

Objetivo 1) .................................................................................................................. 152 Qu es un Thread ?................................................................................................ 152 Las dos formas de crear un Hilo (Thread) .............................................................. 152 Instanciando e Iniciando un hilo. ............................................................................ 153 Objetivo 2) .................................................................................................................. 157 Comentario de este objetivo.................................................................................... 157 Razones por las que un thread puede ser bloqueado............................................... 157 Objetivo 3) .................................................................................................................. 161 Por qu necesitaras el protocolo wait/notify? ...................................................... 161 synchronized ........................................................................................................... 161 wait/notify ............................................................................................................... 162
Seccin 8. El paquete java.awt y su disposicin ...............167

Objetivo 1.................................................................................................................... 167 Nota sobre este objetivo.......................................................................................... 167 Comparando la disposicin de componentes de Java y Visual Basic..................... 167 La filosofa de los administradores de disposicin ................................................. 167 Administradores de disposicin que debes conocer para el examen. ..................... 169 Responsabilidades de los Administradores de Disposicin VS los Contenedores . 169 Curiosidades del administrador BorderLayout ....................................................... 170 El administrador de disposicin GridLayout .......................................................... 171 GridBagLayout ....................................................................................................... 172 Usando gridx y gridy para sugerir la posicin de un componente.......................... 175 ipadx y ipady para controlar el relleno interior de los componentes ...................... 176 Componentes dentro de un panel utilizando GridBagLayout................................. 178 5

Tutorial para el examen de certificacin: SCJP 1.2 Fijando componentes dentro de la cuadrcula......................................................... 180 Elementos GridBag no cubiertos por este ejercicio............................................... 182 Objetivo 2.................................................................................................................... 189 El modelo oyente -Listener- de eventos.................................................................. 189 El modelo de eventos del JDK 1.1.......................................................................... 189
Seccin 9. El paquete java.lang.Math ..........................196

Objetivo 1.................................................................................................................... 196 Nota sobre este objetivo.......................................................................................... 196 abs ........................................................................................................................... 196 ceil........................................................................................................................... 196 floor......................................................................................................................... 197 max y min ............................................................................................................... 197 random .................................................................................................................... 198 round ....................................................................................................................... 198 sin cos tan................................................................................................................ 199 sqrt........................................................................................................................... 199 Resumen.................................................................................................................. 199 Objetivo 2.................................................................................................................... 203 Nota sobre este objetivo.......................................................................................... 203
Seccin 10. El paquete java.util ..............................206

Objetivo 1.................................................................................................................... 206 Nota sobre este objetivo.......................................................................................... 206 Las colecciones antiguas......................................................................................... 206 Las nuevas colecciones ........................................................................................... 206 Set ........................................................................................................................... 207 List .......................................................................................................................... 207 Map ......................................................................................................................... 207 Usando Vectores ..................................................................................................... 208 Usando Hashtables.................................................................................................. 209 BitSet....................................................................................................................... 209
Seccin 11. El paquete java.io ................................214

Objetivo 1.................................................................................................................... 214 Objetivo 2.................................................................................................................... 222 Objetivo 3.................................................................................................................... 228 Objetivo 4.................................................................................................................... 229 FileInputStream and OutputStream ........................................................................ 229 BufferedInputStream y BufferedOutputStream...................................................... 230 DataInputStream y DataOutputStream ................................................................... 230 La clase File......................................................................................................... 231 RandomAccesFile ................................................................................................... 231 Objetivo 5.................................................................................................................... 235 FileInputStream and FileOutputStream .................................................................. 235 RandomAccessFile ................................................................................................. 236

javaHispano. Tu comunidad, tu lenguaje.

Seccin 1. Declaracin y control de Acceso


Objetivo 1.
Escribir cdigo que declare, construya e inicie arreglos de cualquier tipo base, usando cualquiera de las formas permitidas, para declaracin y para inicializacin.
Arreglos.

Los arreglos en Java son similares en sintaxis a los arreglos en otros lenguajes como C/C++ y Visual Basic. Sin embargo, Java elimina la caracterstica de C/C++ mediante la cual puedes pasar los corchetes ([]) accediendo a los elementos y obteniendo sus valores utilizado punteros. Esta capacidad en C/C++, aunque poderosa, propicia la escritura de software defectuoso. Debido a que Java no soporta esta manipulacin directa de punteros, se remueve esta fuente de errores. Un arreglo es un tipo de objeto que contiene valores llamados elementos. Esto te da un conveniente contenedor de almacenamiento para un grupo de valores que pueden modificarse durante el programa, y permite que accedas y cambies los valores segn lo necesites. A diferencia de las variables que son accedidas por un nombre, los elementos de un arreglo son accedidos por nmeros comenzando por cero. De esta manera puedes avanzar a travs del arreglo, accediendo a cada elemento en turno. Todos los elementos de un arreglo deben ser del mimo tipo. El tipo de elementos de un arreglo, se decide cuando se declara el arreglo. Si lo que necesitas es una manera para almacenar un grupo de elementos de tipos diferentes, puedes usar las clases de colecciones, estas son una nueva caracterstica en Java 2 y son discutidas en la seccin 10.

Declaracin sin asignacin.


La declaracin de un arreglo no asigna almacenamiento alguno, sta solo anuncia la intencin de crear un arreglo. Una diferencia significativa con la manera en que C/C++ declara un arreglo es que el tamao no se especifica con el identificador. Por lo tanto lo siguiente causara un error durante la compilacin
int num[5];

El tamao de un arreglo se da cuando este se crea realmente con el operador new:


int num[]; num = new int[5];

Tutorial para el examen de certificacin: SCJP 1.2

Creacin y Declaracin Simultanea.


Lo anterior puede ser compactado en una sola lnea as:
int num[] = new int[5];

Adems los corchetes pueden ser tambin colocados despus del tipo de dato o despus del nombre del arreglo. Por lo tanto son legales las siguientes declaraciones:
int[] num; int num[];

Puedes leer esto de la siguiente manera: Un arreglo de enteros llamado num Un arreglo llamado num de tipo entero.

Arreglos Java VS Arreglos C/C++ .


Una gran diferencia entre java y C/C++ es que en java se conocen de que tamao son los arreglos, y el lenguaje proporciona proteccin para no sobrepasar los limites del arreglo.

Este comentario es particularmente til si vienes de un ambiente de programacin como Visual Basic donde no es muy comn iniciar el conteo de un arreglo desde 0. Tambin ayuda a evitar uno de los mas insidiosos errores de C/C++. Por lo tanto, lo siguiente causar el siguiente error en tiempo de ejecucin:
ArrayIndexOutOfBoundException int[] num = new int [5]; for (int i = 0;i<6;i++){ num[i] = i*2; }

Para recorrer un arreglo, la manera mas comn es a travs del campo length de los arreglos, as:
int [] num = new int[5]; for(int i = 0;i<num.length;i++){ num[i]=i*2; }

javaHispano. Tu comunidad, tu lenguaje.

Los arreglos conocen su tamao.


Solo en caso de que te hayas saltado la comparacin con C/C++ -hecha anteriormentelos arreglos en Java siempre conocen cual es su tamao, y este se representa en el campo length. As, puedes llenar dinmicamente un arreglo con el cdigo siguiente:
int myarray[] = new int [10]; for(int j=0; j<myarray.length; j++){ myarray[j]=j; }

Nota que los arreglos tienen el campo length y no el mtodo length(). Cuando comiences a utilizar Strings usaras el mtodo length, de la siguiente manera:
s.length();

En un arreglo length es un campo (o propiedad) no un mtodo.


Arreglos Java VS Arreglos VB

Los arreglos en Java siempre comienzan desde cero. Los arreglos en VB pueden comenzar desde 1 si se usa la declaracin Option base. En Java no hay equivalente para el comando redim preserve a travs del cual puedes cambiar el tamao de un arreglo sin borrar su contenido. Pero por supuesto puedes crear un nuevo arreglo con un nuevo tamao y copiar los elementos actuales a ese arreglo y obtener el mismo resultado. La declaracin de un arreglo puede tener mltiples conjuntos de corchetes ([]). Java formalmente no soporta los arreglos multidimensionales; sin embargo si soporta arreglos de arreglos; tambin conocidos como arreglos anidados. Una diferencia importante entre los arreglos multidimensionales, como en C/C++ y los arreglos anidados, es que cada arreglo no tiene que ser del mismo tamao. Si vemos un arreglo como una matriz, la matriz no tiene que ser una matriz rectngulo . De acuerdo con la Especificacin del Lenguaje Java:
(http://java.sun.com/docs/books/jls/html/10.doc.html#27805)

El nmero de corchetes indica la profundidad de un arreglo anidado En otros lenguajes esto se conoce como la dimensin de un arreglo. As podras almacenar las coordenadas de un mapa con un arreglo de 2 dimensiones:
int [][];

la 1 dimensin podra ser la coordenada X y la segunda la coordenada Y.


NT.: En otras palabras; cada arreglo puede tener un tamao distinto.

Tutorial para el examen de certificacin: SCJP 1.2

Combinar declaracin con inicializacin.


En vez de ciclarse a travs de un arreglo para llevar a cabo la inicializacin, un arreglo puede ser creado e inicializado a la vez en una sola declaracin. Esto es particularmente recomendable para arreglos pequeos. La siguiente lnea creara un arreglo de enteros y lo llenara con los nmeros 0 hasta el 4.
int k[] = new int[] {0,1,2,3,4};

Observa que en ninguna parte necesitas especificar el nmero de elementos en el arreglo. Puedes analizar esto, preguntndote si el siguiente cdigo es correcto:
Int k = new int[5]{0,1,2,3,4}; // error, no compilara !!!

Puedes crear y llenar arreglos simultneamente con cualquier tipo de dato, por lo tanto puedes crear un arreglo de cadenas, de la siguiente manera:
String s[] = new String [] {Zero,One,Two,Three,Four};

Los elementos de un arreglo pueden ser direccionados como lo haras en C/C++:


String s[] = new String [] {Zero,One,Two,Three,Four}; System.out.println(s[0]);

Esto mostrar la cadena Zero. Ejercicio 1) Crea una clase con un mtodo que simultneamente cree e inicialize un arreglo de cadenas. Inicializa el arreglo con cuatro nombres, despus muestra el primer nombre contenido en el arreglo. Ejercicio 2) Crea una clase que cree un arreglo de cadenas de 5 elementos llamado Fruit en el nivel de clase, pero no lo inicializes con cualquier valor. Crea un mtodo llamado amethod. En amethod inicializa los primeros cuatro elementos con nombres de frutas. Crea otro mtodo llamado modify y cambia el contenido del primer elemento del arreglo Fruit para que contenga la cadena bicycle. Dentro del mtodo modify crea un ciclo for que imprima todos los elementos del arreglo. Solucin sugerida para el ejercicio 1.
public class Bevere{ public static void main(String argv[]){ Bevere b = new Bevere(); b.Claines();

10

javaHispano. Tu comunidad, tu lenguaje.


} public void Claines(){ String[] names= new String[]{"Peter","John","Balhar","Raj"}; System.out.println(names[0]); } }

Nota: La sintaxis para la creacin e inicializacin simultanea no es evidente y vale la pena practicarla. Se pregunt por el primer nombre del arreglo para asegurar que no utilizars names[1].

Solucin Sugerida para el ejercicio 2.


public class Barbourne{ String Fruit[]= new String[5]; public static void main(String argv[]){ Barbourne b = new Barbourne(); b.amethod(); b.modify(); } public void amethod(){ Fruit[0]="Apple"; Fruit[1]="Orange"; Fruit[2]="Bannana"; Fruit[3]="Mango"; } public void modify(){ Fruit[0]="Bicycle"; for(int i=0; i< Fruit.length; i++){ System.out.println(Fruit[i]); } } }

Nota: Cuando el ciclo ejecute la salida de elemento final este ser null.

11

Tutorial para el examen de certificacin: SCJP 1.2

Preguntas. Pregunta 1) Cmo puedes redimensionar un arreglo con una declaracin sencilla manteniendo el contenido original?

Pregunta 2) Quieres averiguar el valor del ltimo elemento de un arreglo. Escribiendo el siguiente Cdigo.Qu pasara cuando lo compiles y ejecutes?
public class MyAr{ public static void main(String argv[]){ int[] i = new int[5]; System.out.println(i[5]); } }

Pregunta 3) Quieres hacer un ciclo a travs de un arreglo y detenerte cuando llegues al ultimo elemento. Siendo un buen programador en Java, y olvidando lo que alguna vez conociste sobre C/C++, sabes que los arreglos contienen informacin acerca de su tamao. Cul de las siguientes sentencias puedes usar?
1)myarray.length(); 2)myarray.length; 3)myarray.size 4)myarray.size();

Pregunta 4) Tu jefe esta complacido por que escribiste el programa Hello World y te ha dado un aumento. Ahora te encomienda que crees un juego como el TicTacToe(o puntos y cruces como lo conoc en mi adolescencia). Decides que para eso necesitas un arreglo multidimensional. Cul de las siguientes lneas realizan el trabajo?
1) 2) 3) 4) int i=new int[3][3]; int[] i=new int[3][3]; int[][] i=new int[3][3]; int i[3][3]=new int[][];

Pregunta 5)

12

javaHispano. Tu comunidad, tu lenguaje. Quieres encontrar una manera ms elegante para llenar un arreglo que a travs de un ciclo con la sentencia for. Cul de las siguientes lneas usaras?
1) myArray{ [1]="One"; [2]="Two"; [3]="Three"; end with 2)String s[5]=new String[] {"Zero","One","Two","Three","Four"}; 3)String s[]=new String[] {"Zero","One","Two","Three","Four"}; 4)String s[]=new String[]={"Zero","One","Two","Three","Four"};

Respuestas Respuesta 1) No puedes redimensionar un arreglo. Necesitas crear un nuevo arreglo temporal con un tamao diferente y llenarlo con el contenido del arreglo original. Java Proporciona contenedores redimencionables con clases como Vector o uno de los miembros de la clase collection .

Respuesta 2) Intentar avanzar mas all del final del arreglo genera un error en tiempo de ejecucin. Debido a que los arreglos son indexados desde 0, el elemento final ser i[4] y no
i[5].

Respuesta 3)
2) myarray.length;

Respuesta 4)
3) int[][] = new int[3][3];

Respuesta 5)
3) String s[] = new String[]{Zero,One,Two,Three,Four};

13

Tutorial para el examen de certificacin: SCJP 1.2


Otras Fuentes de este tema:

Este tema es cubierto en el Tutorial de Sun en: http://java.sun.com/docs/books/tutorial/java/data/arraysAndStrings.html Richard Baldwin trata este tema en: http://www.Geocities.com/Athens/Acropolis/3797/Java028.htm Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj1 Bruce Eckel Thinking In Java Captulo 8

14

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2.
Declarar clases, clases internas, mtodos, variables de instancia estticas, variables y variables automticas(mtodos locales), haciendo un uso apropiado de todos los modificadores permitidos (como son: public, final, static, abstract, y dems). Conocer importancia de cada uno de estos modificadores ya sea solos o en combinacin Comentario sobre este objetivo Encuentro un poco molesto que en el objetivo se use la frase y dems. Supongo que esto significa que debes estar consciente de los modificadores:
native transient synchronized volatile

Comparando las clases de C++/VB con las de Java.


Debido a que Java fue diseado para facilitar que programadores C++ lo aprendieran, este tiene muchas similitudes en la manera en que ambos lenguajes trabajan con las clases. Ambos lenguajes tienen herencia, polimorfismo, y ocultamiento de datos usando modificadores de visibilidad. Algunas de sus diferencias fueron hechas para hacer de Java un lenguaje ms fcil de aprender y usar. El lenguaje C++ implementa la herencia mltiple y as una clase puede tener ms de un padre (o clase base) Java nicamente permite la herencia simple, es decir, las clases pueden tener nicamente un padre. Para sobreponer esta limitacin, Java tiene una caracterstica llamada: Interfaces, a la cual los diseadores del lenguaje le decidieron dar algunas de las ventajas de la herencia mltiple, pero sin las desventajas. Todas las clases en Java son descendientes de una gran clase antecesora llamada Object.

El rol de las clases en Java


Las clases son el corazn de Java, todo el cdigo en Java ocurre dentro de una clase. No hay un concepto de cdigo llano y de posicin libre. Hasta la ms sencilla aplicacin HelloWorld involucra la creacin de una clase. Para indicar que una clase desciende de otra clase se usa la palabra clave extends. Si no se usa extends, la clase descender de la clase Object lo cual proporciona a la clase creada, algunas funciones bsicas incluyendo la habilidad para mostrar su nombre y algunas de las capacidades requeridas en los Threads.

15

Tutorial para el examen de certificacin: SCJP 1.2

La clase ms sencilla.
Los requerimientos mnimos para definir una clase son: la palabra clave class, el nombre de la clase y las llaves de apertura y cerradura. Entonces:
class classname {}

es una definicin sintacticamente correcta para una clase, pero no es una clase particularmente til (sorprendentemente, me he encontrado definiendo clases como esta, cuando creo ejemplos para ilustrar la herencia) Normalmente una clase tambin incluir un especificador de acceso antes de la palabra clave class y por supuesto, el cuerpo de la clase entre las llaves. As, lo siguiente es una plantilla mas sensata para definir una clase:
public class classmane{ // el cuerpo de la clase va ac }

Creando una clase sencilla- HelloWorld


Este es un sencillo programa HelloWorld que mostrar: la cadena hello world en la pantalla.
public class HelloWorld{ public static void main(String argv[]){ System.out.println("hello world"); } }//Fin de la Definicin de la clase

La palabra clave public es un modificador de visibilidad que indica que la clase deber ser visible para cualquier otra clase. Solo una clase por archivo puede ser declarada publica. Si declaras mas de una clase en un archivo como publica, ocurrir un error en tiempo de ejecucin. Observa que Java es sensible a maysculas en todos los aspectos. El archivo que contenga esta clase deber llamarse HelloWorld.java La palabra clave class indica que una clase comienza a ser definida y HelloWorld es el nombre de la clase. Observa que la llave de cierre que finaliza la definicin de la clase no involucra un punto y coma de cerradura. El comentario:
//Fin de la Definicin de la clase

Usa el estilo de comentario de una sola lnea que esta disponible en C/C++. Java tambin comprende los comentarios multilneas de la forma /* */.

La magia del nombre main

16

javaHispano. Tu comunidad, tu lenguaje. Dando a un mtodo la siguiente forma, est obtiene cierta significancia (o magia) cuando indica a Java que es aqu en donde el programa debe empezar a ejecutarse. (similar al main del lenguaje C).
public static void main(String argv[]){

Esta lnea indica que esta definindose un mtodo llamado main, y que toma como parmetros (o argumentos) a un arreglo de cadenas. Este mtodo es publico, es decir es visible desde cualquier parte de la clase. La palabra clave static indica que este mtodo puede ejecutarse sin crear una instancia de la clase. Si eso no significa nada para ti, no te preocupes, en su momento se cubrirn con detalle los mtodos estticos (static) en otra parte de este tutorial. La palabra clave void indica el tipo de dato retornado por el mtodo cuando se llama. Usar void indica que ningn valor ser retornado. El parmetro del mtodo main:
String argv[]

Indica que el mtodo toma un arreglo de tipo String. Los corchetes indican como ya vimos- un arreglo. Observa que el tipo de dato String comienza con una S mayscula. Esto es importante ya que Java es totalmente sensible a las maysculas. Sin estas exactitudes, la Maquina virtual de Java (JVM) no reconocer el mtodo como el lugar en donde se debe comenzar la ejecucin del programa.

Creando una instancia de una Clase


La aplicacin HelloWorld, como describ anteriormente, es til para ilustrar la ms sencilla de las aplicaciones que puedes crear. Pero le falta mostrar uno de los elementos ms cruciales al usar las clases, la palabra clave new. La cual indica la creacin de una nueva instancia de la clase. En la aplicacin HelloWorld esto no era necesario ya que el nico mtodo que se llam era System.out.println que es un mtodo esttico y no requiere la creacin de una clase que utilice la palabra new. Los mtodos estticos pueden acceder solo a variables estticas, de las que slo puede existir una instancia por la clase. La aplicacin de HelloWorld puede modificarse ligeramente para ilustrar la creacin de una nueva instancia de una clase.
public class HelloWorld2{ public static void main(String argv[]){ HelloWorld2 hw = new HelloWorld2(); hw.amethod(); } public void amethod(){ System.out.println("Hello world"); } }

17

Tutorial para el examen de certificacin: SCJP 1.2 Este cdigo crea una nueva instancia de si mismo en la lnea:
HelloWorld2 hw = new HelloWorld2();

Esta sintaxis para crear una nueva instancia de una clase es bsica para el uso de clases. Observa cmo el nombre de la clase aparece dos veces. La primera vez indica el tipo de dato de la referencia a la clase. Esta necesidad no es la misma que el tipo actual de la clase puesto que sta se indica despus de usar la palabra clave new. El nombre de esta instancia de la clase es hw. ste simplemente es un nombre escogido para una variable. Este es un nombramiento convencional (es decir, utilizando la convencin para escritura de cdigo Java)ya que una instancia de una clase empieza con una letra minscula, considerando que la definicin de una clase empieza con una letra mayscula. El parntesis vaco para el nombre de la clase HelloWorld() indica que la clase est crendose sin algn parmetro en su constructor. Si estuvieras creando una instancia de una clase que se inicializa con un valor o un arreglo como la clase Label o Button el parntesis contendra uno o mas valores de inicializacin.

Creando Mtodos.
Como ilustro en el ltimo ejemplo HelloWorld2, un mtodo en Java es similar a una funcin en C/C++ y a una funcin o sub funcin en Visual Basic. El mtodo llamado amethod en este ejemplo se declara como:
public

que indica que puede accederse desde cualquier parte. Retorna el tipo:
void

Indicando que ningn valor ser retornado. Y los parntesis vacos indican que no toma parmetros. El mismo mtodo se podra haber definido de estas maneras alternativas:
private void amethod(String s) private void amethod(int i, String s) protected void amethod(int i)

Estos ejemplos ilustran algunas otras firmas tpicas de declaracin de mtodos. El uso de las palabras clave private y protected se cubrir en otro apartado. La diferencia entre los mtodos de Java y mtodos en lenguajes no orientados a objetos como C es que los mtodos pertenecen a una clase. Esto significa que se llaman usando la anotacin del punto que indica la instancia de la clase a la que el mtodo pertenece (Los mtodos estticos son una excepcin a esto pero no te preocupes sobre ellos por el momento) 18

javaHispano. Tu comunidad, tu lenguaje.

As en HelloWorld2 el mtodo amethod se llamo as:


HelloWorld hw = new HelloWorld(); hw.amethod();

Si se hubieran creado otras instancias de la clase HelloWorld el mtodo podra llamarse desde cada instancia de la clase. Cada instancia de la clase tendra acceso a sus propias variables. As lo siguiente involucrara la llamada al cdigo del mtodo amethod de las diferentes instancias de la clase.
HelloWorld hw = new HelloWorld(); HelloWorld hw2 = new HelloWorld(); hw.amethod(); hw2.amethod();

Las dos instancias de la clase: hw y hw2 podran tener acceso a variables diferentes.

Variables Automticas
Las variables automticas son las variables de los mtodos. Estas entran en el alcance del programa cuando empieza a ejecutarse el cdigo del mtodo y dejan de existir una vez que el mtodo deja de ejecutarse. Son slo visibles dentro del mtodo y son tiles principalmente para la manipulacin de datos temporales. Si quieres que un valor permanezca entre las llamadas de un mtodo entonces la variable necesita ser creada al nivel de la clase. Una variable automtica ser la "sombra" de una variable de nivel de clase. As el cdigo siguiente mostrar 99 y no 10:
public class Shad{ public int iShad=10; public static void main(String argv[]){ Shad s = new Shad(); s.amethod(); }//fin de main public void amethod(){ int iShad=99; System.out.println(iShad); }//fin de amethod }

19

Tutorial para el examen de certificacin: SCJP 1.2

Modificadores y Encapsulamiento.
Los modificadores de visibilidad son parte del mecanismo de encapsulamiento para Java. El encapsulamiento permite la separacin de la interfase y la implementacin de mtodos.

A menudo estos mtodos son para recuperar y actualizar los valores de una variable local privada. Son conocidos como mtodos accessor (acceder o obtener el valor de la variable) y mutator (modificar el contenido de una variable). La convencin para nombrar a estos mtodos es setFoo para modificar y getFoo para obtener el contenido de una variable. As si estuvieras almacenado una variable llamada age deberas hacerla privada y actualizarla con:
setAge

y recuperar su valor con:


getAge

Usando cdigo para modificar variables; el valor de la variable tambin puede verificarse, por ejemplo: si el valor esta dentro de un rango en particular o revisar si es un numero positivo. Private Las variables privadas son slo visibles dentro de la misma clase donde se crean. Esto significa que NO son visibles dentro de las subclases. Esto permite que la variable sea aislada de ser modificada por cualquier mtodo, exceptuando aquellos en la clase actual. Como se dijo anteriormente, esto es til para separar la interfase de la implementacin.
class Base{ private int iEnc=10; public void setEnc(int iEncVal){ if(iEncVal < 1000){ iEnc=iEncVal; }else System.out.println("Enc value must be less than 1000"); //Or Perhaps thow an exception }//End if } public class Enc{ public static void main(String argv[]){ Base b = new Base(); b.setEnc(1001); }//End of main }

20

javaHispano. Tu comunidad, tu lenguaje.

Public El modificador public puede aplicarse a una variable (campo) o una clase. Es probablemente el primer modificador que conociste aprendiendo Java. Si revisas el cdigo para HelloWorld.Java, que se program en un principio, la clase se declar como:
public class HelloWorld

Esto es porque para iniciar el mtodo mgico la JVM, slo revisa en una clase declarada como publica:
public static void main(String argv[])

Una clase pblica tiene alcance global, y una instancia puede crearse desde cualquier parte dentro o fuera de un programa. nicamente una clase en un archivo puede definirse con la palabra clave public. Si defines ms de una clase en un archivo con la palabra clave public el compilador generar un error
class Base { public int iNoEnc=77; } public class NoEnc{ public static void main(String argv[]){ Base b = new Base(); b.iNoEnc=2; System.out.println(b.iNoEnc); }//End of main }

Observa que generalmente sta no es la manera sugerida ya que no permite ninguna separacin entre la interfase y implementacin del cdigo. Si decidieras cambiar el tipo de dato de iNoEnc, tendras que modificar la implementacin de cada parte del cdigo externo que lo modifica. Protected El modificador protected es una pequea rareza. Una variable protegida es visible dentro de una clase, en una subclase, y en el mismo paquete, pero no en otra parte. La cualidad de ser visible dentro del mismo paquete puede darle ms visibilidad de la que podras sospechar. Cualquier clase que est en el mismo directorio se considera que est en el paquete predefinido, y as las clases protegidas sern visibles. Esto significa que una variable protegida tiene ms visibilidad que una variable definida sin modificador de acceso.

21

Tutorial para el examen de certificacin: SCJP 1.2 Se dice que una variable definida sin modificador de acceso tiene visibilidad predefinida. La visibilidad predefinida significa que una variable puede verse dentro de la clase, y desde otra parte dentro del mismo paquete, pero no desde una subclase que no est en el mismo paquete. Static
Static no es directamente un modificador de visibilidad, aunque en la prctica tiene este efecto. El modificador static puede aplicarse a una clase, a un mtodo y una

variable. Marcando una variable como esttica se indica que slo una copia de esa variable existir por clase. Esto est en contraste con las variables normales donde por ejemplo una copia de una variable integer pertenece a cada instancia de una clase. As en el ejemplo siguiente existirn tres instancias de la variable integer iMyVal y cada instancia podra contener un valor diferente.
class MyClass{ public int iMyVal=0; } public class NonStat{ public static void main(String argv[]){ MyClass m1 = new MyClass(); m1.iMyVal=1; MyClass m2 = new MyClass(); m2.iMyVal=2; MyClass m3 = new MyClass(); m3.iMyVal=99; //Esto mostrar 1. Ya que cada instancia de // la clase tiene su propia copia de MyVal System.out.println(m1.iMyVal); }//End of main }

El Ejemplo siguiente muestra que pasa cuando tienes mltiples instancias de una clase que contiene una variable esttica, en este ejemplo la variable esttica es iMyEval.
class MyClass{ public static int iMyVal=0; }//End of MyClass public class Stat{ public static void main(String argv[]){ MyClass m1 = new MyClass(); m1.iMyVal=0; MyClass m2 = new MyClass(); m2.iMyVal=1; MyClass m3 = new MyClass(); m2.iMyVal=99; //Debido a que iMyVal es static, //hay slo una copia de l no importa

22

javaHispano. Tu comunidad, tu lenguaje.


//cuantas instancias de la clase se creen. //Este cdigo mostrar el valor de 99 System.out.println(m1.iMyVal); }//End of main }

Ten presente que no puedes acceder a variables no estticas desde dentro de un mtodo esttico. As lo siguiente causar un error en tiempo de compilacin.
public class St{ int i; public static void main(String argv[]){ i = i + 2;//Causar un error al compilar } }

Un mtodo esttico no puede ser sobreescrito para ser no esttico en una clase hija.

Un mtodo esttico no puede ser sobreescrito para ser no esttico en una clase hija. No hay ninguna regla similar con referencia a la sobrecarga. El cdigo siguiente causar un error cuando intentes sobreescribir el mtodo amethod de la clase Base para ser no esttico.
class Base{ public static void amethod(){ } } public class Grimley extends Base{ public void amethod(){}//Causa un error en tiempo de compilacin }

El compilador Jikes de IBM produce el siguiente error:


Found 1 semantic error compiling "Grimley.java": 6. public void amethod(){} <-------> *** Error: The instance method "void amethod();" cannot override the static method "void amethod();" declared in type "Base"

Native El modificador native slo se usa para los mtodos e indica que el cuerpo del cdigo esta escrito en un lenguaje que no es Java como C y C++. Se escriben a menudo mtodos

23

Tutorial para el examen de certificacin: SCJP 1.2 nativos para propsitos especficos de la plataforma como acceder a algn elemento de hardware del cual la Maquina Virtual de Java no este consciente. Otra razn es utilizarlo donde se requiere mayor desempeo. Un mtodo nativo termina con punto y coma en lugar de un bloque del cdigo. As lo siguiente llamara una rutina externa, escrita quizs en C++,
public native fastcalc();

Abstract Es fcil pasar por alto el modificador abstract y perderse algunas de sus implicaciones. Es la clase de modificador que a los examinadores les gusta para hacer preguntas complicadas. El modificador abstracto puede aplicarse a las clases y a los mtodos. Cuando se aplica a un mtodo indica que ste no tendr cuerpo y el cdigo slo puede ejecutarse cuando se implemente en una clase hija. Sin embargo hay algunas restricciones sobre cuando y donde puedes tener mtodos abstractos y reglas sobre las clases que los contienen. Cuando se aplica a una clase, indica que la clase tiene un por lo menos mtodo abstracto.

Si una clase tiene algn mtodo abstracto esta debe ser asimismo declarada abstracta .

Sin embargo, no te distraigas pensado que una clase abstracta no puede tener mtodos no abstractos. Cualquier clase que descienda de una clase abstracta debe implementar los mtodos abstractos de la clase base o debe declararlos abstractos ella misma. Tienden estas reglas a generar la pregunta por qu querras crear mtodos abstractos? Los mtodos abstractos son principalmente beneficiosos a los diseadores de clases. Ofrecen al diseo de una clase una manera de crear un prototipo para mtodos que han de ser implementados, pero la implementacin real queda a las personas que usan las clases despus. Aqu hay un ejemplo de una clase abstracta con un mtodo abstracto. De nuevo nota que la propia clase se declara abstracta, de otra manera habra ocurrido un error en tiempo de compilacin. La siguiente clase es abstracta y se compilar sin problemas:
public abstract class abstr{ public static void main(String argv[]){ System.out.println("hello in the abstract"); } public abstract int amethod();

24

javaHispano. Tu comunidad, tu lenguaje.


}

Final El modificador final indica que un mtodo no puede ser heredado. Otra manera de entender esto es que una clase final no puede ser una clase padre. Cualquier mtodo en una clase final es automticamente final. Esto puede ser til si no quieres que otros programadores "hechen a perder tu cdigo". Otro beneficio es la eficacia puesto que el compilador tiene menos trabajo al trabajar con un mtodo final. Esto se cubre mejor en el Volumen 1 de Core Java. El cdigo siguiente ilustra el uso del modificador final en una clase. Este cdigo mostrar la cadena "amethod":
final class Base{ public void amethod(){ System.out.println("amethod"); } } public class Fin{ public static void main(String argv[]){ Base b = new Base(); b.amethod(); } }

Shynchronized La palabra clave synchonized se usa para prevenir que ms de un thread acceda a un bloque de cdigo a la vez. Ve la seccin 7 sobre threads para entender ms cmo funciona esto. Transient La palabra clave transient es uno de los modificadores frecuentemente menos usados. Indica que una variable no debe escribirse fuera cuando una clase es serializada. Volatile Probablemente no conseguirs realizar alguna pregunta sobre la palabra clave volatile. Lo peor que conseguirs es reconocer que realmente es un palabra clave de Java. Segn Barry Boone: "le dice al compilador que una variable puede cambiar asincrnicamente debido a los threads" 25

Tutorial para el examen de certificacin: SCJP 1.2

Acepta que es parte del lenguaje y entonces mejor preocpate por otras cosas.

Usando modificadores en combinacin


Los modificadores de visibilidad no pueden usarse en combinacin, as una variable no puede ser privada y pblica, pblica y protegida o protegido y privada. Puedes tener combinaciones de los modificadores de visibilidad y los modificadores mencionados, por supuesto, en mi lista "y dems".

native transient synchronized volatile

As puedes tener un mtodo public static native. Donde pueden usarse los modificadores Modificador Mtodo Variable clase public private protected abstract final transient native volatile si si si si si no si no si si si no si si no si si si(anidable) si(anidable) si si no no no

Ejercicio 1) Crea un archivo llamado Whitley.java. En este archivo define una clase llamada Base con un mtodo abstracto llamado lamprey que retorne un valor de tipo int. En el mismo archivo crea una clase llamada Whitley que descienda de la clase Base. Proporciona a la clase Whithley un mtodo llamado lamprey con el cdigo necesario para mostrar en pantalla la cadena lamprey. Crea un mtodo nativo para la clase llamado mynative. Ahora compila y ejecuta el cdigo. Ejercicio 2)

26

javaHispano. Tu comunidad, tu lenguaje. Crea una clase publica llamada Malvern. Crea una clase interna y privada llamada Great que tenga un mtodo llamado show de la forma public void. Haz que este mtodo muestre en pantalla la cadena Show. Proporciona a la clase Malvern un mtodo publico llamado go que cree una instancia de Great y despus de ser instanciada llame al mtodo show. En el mtodo main de la clase Malvern crea una instancia de s misma. Haz que esta instancia llame al mtodo go. Compila y ejecuta el cdigo.

Solucin sugerida para el ejercicio 1.


abstract class Base{ abstract int lamprey(); } public class Whitley extends Base{ public static void main(String argv[]){ } public int lamprey(){ System.out.println("lamprey"); return 99; } native public void mynative(); }

Solucin sugerida para el ejercicio 2.


public class Malvern{ public static void main(String argv[]){ Malvern m = new Malvern(); m.go(); } public void go(){ Great g = new Great(); g.show(); } private class Great{ public void show(){ System.out.println("Show"); } } }

27

Tutorial para el examen de certificacin: SCJP 1.2

Preguntas. Pregunta 1) Qu pasar cuando intentes compilar y ejecutar este cdigo?


abstract class Base{ abstract public void myfunc(); public void another(){ System.out.println("Another method"); } } public class Abs extends Base{ public static void main(String argv[]){ Abs a = new Abs(); a.amethod(); } public void myfunc(){ System.out.println("My func"); } public void amethod(){ myfunc(); } }

1) El cdigo se compilar y se ejecutar, mostrando la cadena My func 2) El cdigo indicara que la clase Base no tiene mtodos abstractos. 3) El cdigo se compilara pero indicar un error en tiempo de ejecucin (run time error): la clase base no tiene mtodos abstractos 4) El compilador indicara que el mtodo myfunc en la clase Base no tiene cuerpo. Pregunta 2) Qu pasara cuando intentes compilar y ejecutar este cdigo?
public class MyMain{ public static void main(String argv){ System.out.println("Hello cruel world"); } }

28

javaHispano. Tu comunidad, tu lenguaje. 1) El compilador indicara que main es una palabra reservada y no puede ser usada para nombrar una clase. 2) El cdigo se compilar y cuando se ejecute mostrara en pantalla la cadena Hello cruel world. 3) El cdigo se compilara pero indicar un error en tiempo de ejecucin: el constructor no esta definido. 4) El cdigo se compilara pero indicara que la funcin main no esta definida correctamente.

Pregunta 3) De los siguientes cuales son modificadores de Java?


1) 2) 3) 4) public private friendly transient

Pregunta 4) Qu pasar cuando intentes compilar y ejecutar este cdigo?


class Base{ abstract public void myfunc(); public void another(){ System.out.println("Another method"); } } public class Abs extends Base{ public static void main(String argv[]){ Abs a = new Abs(); a.amethod(); } public void myfunc(){ System.out.println("My func"); } public void amethod(){ myfunc(); } }

1) El cdigo se compilar y se ejecutar, mostrando la cadena My func 2) El compilador indicar que la clase Base no esta declarada como abstracta. 3) El cdigo se compilar pero indicar un error en tiempo de ejecucin: la clase base no tiene mtodos abstractos 4) El compilador indicar que el mtodo myfunc en la clase Base no tiene cuerpo.

29

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 5) Para que defines un mtodo como nativo? 1) Para conseguir acceder a Hardware desconocido por Java 2) Para definir un nuevo tipo de dato como un entero sin signo. 3) Para escribir cdigo optimizado para el mejor desempeo en un lenguaje como C/C++. 4) Para superar la limitacin del alcance privado de un mtodo

Pregunta 6) Qu pasar cuando intentes compilar y ejecutar este cdigo?


class Base{ public final void amethod(){ System.out.println("amethod"); } } public class Fin extends Base{ public static void main(String argv[]){ Base b = new Base(); b.amethod(); } }

1) Un error en tiempo de compilacin indicando que una clase con algn mtodo final debe ser declarado final por si misma. 2) Un error en tiempo de compilacin indicar que no puedes heredar de una clase con mtodos final 3) Un error en tiempo de ejecucin indicando que Base no esta definida como
final

4) xito en la compilacin y al ejecutarse mostrar en pantalla amethod.

Pregunta 7) Qu pasar cuando intentes compilar y ejecutar este cdigo?


public class Mod{ public static void main(String argv[]){ } public static native void amethod(); }

1) Error en la compilacin: mtodo nativo no puede ser static. 30

javaHispano. Tu comunidad, tu lenguaje. 2) Error en la compilacin: mtodo nativo debe retornar algn valor. 3) Compilacin correcta pero habr un error en tiempo de ejecucin a menos que hallas hecho cdigo para hacer til el mtodo nativo. 4) Compilacin y ejecucin sin error.

Pregunta 8) Qu pasar cuando intentes compilar y ejecutar este cdigo?


private class Base{} public class Vis{ transient int iVal; public static void main(String elephant[]){ } }

1) Un error en tiempo compilacin: la clase Base no puede ser privada. 2) Un error en tiempo de compilacin indicando que un entero no puede ser
transient

3) Un error en tiempo de compilacin indicando que transient no es un tipo de dato. 4) Un error en tiempo de compilacin indicando que el mtodo main esta deformado

Pregunta 9) Qu pasara cuando intentes compilar y ejecutar estos dos archivos en el mismo directorio?
//Archivo P1.java package MyPackage; class P1{ void afancymethod(){ System.out.println("What a fancy method"); } } //Archivo P2.java public class P2 extends P1{ afancymethod(); }

1) Ambos se compilarn y P2 mostrar en pantalla Wath a fancy method cuando se ejecute. 2) No se compilar ninguno. 3) Ambos se compilarn pero P2 tendr un error en tiempo de ejecucin. 4) P1 se compilar limpiamente pero P2 tendr un error al compilarse.

31

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 10) Cules de las declaraciones siguientes son legales?


1) 2) 3) 4) public protected amethod(int i) public void amethod(int i) public void amethod(void) void public amethod(int i)

Respuestas. Respuesta 1) 1) El cdigo se compilara y se ejecutara, mostrando la cadena My func Una clase abstracta puede tener mtodos no abstractos, pero cualquier clase que descienda de ella, debe implementar todos los mtodos abstractos. Respuesta 2) 1) El cdigo se compilara pero indicara que la funcin main no esta definida correctamente. La funcin main recibe un String en lugar de un arreglo de String que es lo correcto. Respuesta 3) 1) public 2) private 4) transient Aunque algunos textos usan la palabra friendly cuando tratan el tema de visibilidad, esta no es una palabra reservada de Java. Toma en cuenta que ser casi seguro que el examen contenga problemas que te pidan que identifiques palabras claves de Java en una lista. Respuesta 4) 2) El compilador indicara que la clase Base no esta declarada como abstracta. El mensaje de error utilizando JDK 1.1. es:
Abs.java:1: class Base must be declared abstract. It does not define void myfunc () from class Base. class Base{

32

javaHispano. Tu comunidad, tu lenguaje.


^ 1 error

Respuesta 5) 1) Para conseguir acceder a hardware desconocido por Java 3) Para escribir cdigo optimizado para el mejor desempeo en un lenguaje como C/C++ Aunque la creacin de cdigo PURE JAVAes altamente conveniente, particularmente para permitir la independencia de plataforma, no debe de tomarse como una religin, y hay ocasiones en que se requiere el cdigo nativo. Respuesta 6) 4)xito en la compilacin y al ejecutarse mostrar en pantalla amethod. Este cdigo llama a una versin de amethod de la clase Base. Si intentas implementar una versin sustituida del mtodo en la clase Fin conseguirs un error en tiempo de compilacin. Respuesta 7) 4)Compilacin y ejecucin sin error. Esta lnea no es una llamada a un mtodo nativo solo se esta declarando- y por lo tanto no ocurre un error en la ejecucin. Respuesta 8) 1)Un error en tiempo compilacin: la clase Base no puede ser privada. Una clase de un nivel alto, al igual que una clase base, no puede ser declarada como privada Respuesta 9) 4)P1 se compilar limpiamente pero P2 tendr un error al compilarse. Aunque P2 esta en el mismo directorio que P1, debido a que P1 fue declarado como parte de un paquete, P1 no esta visible para P2. Respuesta 10) 2)public void amethod(int i) Si pensaste que la opcin 3 es legal utilizando como parmetro el argumento void, debes quitarte un poco de C/C++ de la cabeza. 33

Tutorial para el examen de certificacin: SCJP 1.2 La opcin 4 no es legal porque el tipo de datos debe aparecer despus de cualquier especificador de acceso.
Otras Fuentes para este tema. Este tema es cubierto en el tutorial de Sun como Modificadores de clases: http://java.sun.com/docs/books/tutorial/reflect/class/getModifiers.html Controlando el acceso a los miembros de una clase: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html Richard Baldwin Cubre este tema en http://www.Geocities.com/Athens/Acropolis/3797/Java040.htm Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj2 Bruce Eckel Thinking in Java Chapter 5 (aunque tiene la cabeza llena de C++ e insiste en incluir el modificador friendly)

34

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 3.
Para una clase dada, determinar si se debe crear un constructor predefinido, y si ese es el caso, declarar el prototipo de ese constructor.

Nota de este objetivo


ste es un objetivo pequeo pero oportuno, que se concentra en un aspecto fcilmente pasado por alto en Java

Qu es un constructor?
Necesitas comprender el concepto de constructor para entender este objetivo. Brevemente, es el cdigo que se ejecuta automticamente cuando se crea la clase. Los constructores a menudo se usan para iniciar valores en la clase. Los constructores tienen el mismo nombre de a clase y no retornan ningn valor. En el examen puedes encontar preguntas sobre mtodos que tengan el mismo nombre de la clase pero que retornan algn tipo, como int o String. Ten cuidado y asegrate que cualquier mtodo que asumas que es un constructor no debe retornar algn tipo de dato. Aqu hay un ejemplo de una clase con un constructor que muestra "Greetings from Crowle" cuando se crea una instancia de la clase.
public class Crowle{ public static void main(String argv[]){ Crowle c = new Crowle(); } Crowle(){ System.out.println("Greetings from Crowle"); } }

Cundo proporciona Java el constructor predefinido?


Si no defines especficamente algn constructor, el compilador inserta fuera de escena un constructor invisible con cero parmetros, frecuentemente esto solo es de importancia terica, pero lo verdaderamente importante es que solo recibes el constructor predefinido con cero parmetros si no creas algn constructor propio.

35

Tutorial para el examen de certificacin: SCJP 1.2

Si creas tus propios constructores, Java ya no te proporciona el constructor predefinido con cero parmetros. As que tienes que especificarlo.

En cuanto creas algn constructor propio, pierdes el constructor predefinido con cero parmetros. Si intentas crear una instancia de una clase, sin pasarle algn parmetro (invocando la clase con el constructor con cero parmetros), obtendrs un error. As, cuando crees algn constructor para una clase necesitars crear el constructor con cero parmetros. Esta es una de las razones por las que generadores de cdigo como Borland/Inprise o JBuilder, crean un constructor con cero parmetros cuando generan el esqueleto de una clase. El ejemplo siguiente muestra cdigo que no compilar. Cuando el compilador verifica la creacin de la instancia c de la clase Base, inserta una llamada al constructor con cero parmetros. Debido a que la clase Base tiene un constructor que recibe un entero, el constructor con cero parmetros ya no esta disponible. Esto se puede arreglar creando en la clase Base un constructor con cero parmetros que no haga nada.
//Advertencia: no se compilar class Base{ Base(int i){ System.out.println("single int constructor"); } } public class Cons { public static void main(String argv[]){ Base c = new Base(); } } //Esto si se compilar class Base{ Base(int i){ System.out.println("single int constructor"); } Base(){} } public class Cons { public static void main(String argv[]){ Base c = new Base(); } }

36

javaHispano. Tu comunidad, tu lenguaje.

El prototipo del constructor predefinido


El objetivo te pide que estes consciente del prototipo del constructor predefinido. Naturalmente no debe tener ningn parmetro. La predefinicin ms evidente es no tener ningn especificador de alcance, pero puedes definir un constructor como pblico o protegido. Los constructores no pueden ser nativos, abstractos, estticos, sincronizados ni finales. Ese pedazo de informacin se deriv directamente de un mensaje de error del compilador. Parece que la calidad de los mensajes de error estn mejorando con las nuevas versiones de Java. He odo que el nuevo compilador de Java de IBM tiene un buen informador de errores. Podran aconsejarte que tuvieras disponible ms de una versin del compilador de Java para verificar tu cdigo y buscar los errores. Ejercicios Ejercicio 1) Crea una clase llamada Salwarpe con un mtodo llamado hello que muestre la cadena hello. En el mtodo main de la clase crea una instancia de s misma llamada s1 y llama al mtodo hello desde la instancia. Compila y ejecuta el programa para que puedas ver el resultado. Ejercicio 2) Usando todava el archivo Salwarpe.java comenta las lneas que crean la instancia y llaman al mtodo hello. Crea un constructor publico para la clase que tome un parmetro entero y muestre el valor del entero. Crea una instancia de la clase llamada s2 proporcinale el valor de 99 al constructor. Compila y ejecuta el programa para que puedas ver mostrado el resultado. Ejercicio 3) Descomenta las lneas que crean la instancia s1 y modifica el programa para que compile, ejecute y muestre ambos la cadena Hello y el numero 99. Solucin sugerida para el ejercicio 1.
public class Salwarpe { public static void main(String argv[]){ Salwarpe s1 = new Salwarpe(); s1.hello(); } public void hello(){ System.out.println("Hello"); }

37

Tutorial para el examen de certificacin: SCJP 1.2


}

Solucin sugerida para el ejercicio 2.


public class Salwarpe { public static void main(String argv[]){ //Salwarpe s1 = new Salwarpe(); //s1.hello(); Salwarpe s2 = new Salwarpe(99); } public void hello(){ System.out.println("Hello"); } public Salwarpe(int i){ System.out.println(99); } }

Solucin sugerida para el ejercicio 3.


public class Salwarpe { public static void main(String argv[]){ Salwarpe s1 = new Salwarpe(); s1.hello(); Salwarpe s2 = new Salwarpe(99); } public void hello(){ System.out.println("Hello"); } public Salwarpe(int i){ System.out.println(99); } public Salwarpe(){} }

Observa como fue necesario crear el constructor con cero parmetros para este ltimo ejercicio. Una vez que has creado algn constructor para una clase, Java ya no te proporciona tras escena el constructor con cero parmetros que estaba disponible en el ejercicio 1.

38

javaHispano. Tu comunidad, tu lenguaje. Preguntas Pregunta 1) Dada la siguiente definicin de clase:


class Base{ Base(int i){} } class DefCon extends Base{ DefCon(int i){ //XX } }

Cul se las lneas siguientes ser individualmente valida si se sustituye por la lnea marcada con //XX?
1) super(); 2) this(); 3) this(99); 4)super(99);

Pregunta 2) Dada la siguiente definicin de clase:


public class Crowle{ public static void main(String argv[]){ Crowle c = new Crowle(); } Crowle(){ System.out.println("Greetings from Crowle"); } }

Cul es el tipo de dato retornado por el constructor? 1) null 2) integer 3) String 4) no es retornado algn tipo de dato

Pregunta 3) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo? 39

Tutorial para el examen de certificacin: SCJP 1.2

public class Crowle{ public static void main(String argv[]){ Crowle c = new Crowle(); } void Crowle(){ System.out.println("Greetings from Crowle"); } }

1)Se compilara y mostrar la cadena Greetings from Crowle. 2)Error en tiempo de compilacin: un constructor no puede retornar un tipo de dato. 3)Se compilara y mostrar la cadena void. 4)Se compilara y no mostrar nada al ejecutarse.

Pregunta 4) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


class Base{ Base(int i){ System.out.println("Base"); } } class Severn extends Base{ public static void main(String argv[]){ Severn s = new Severn(); } void Severn(){ System.out.println("Severn"); } }

1)Se compilar al ejecutarse y mostrar la cadena Seven. 2)Error en tiempo de compilacin. 3)Se compilar y no mostrar nada al ejecutase 4)Se compilar y mostrar la cadena Base

Pregunta 5) Cules de las siguientes declaraciones son verdaderas? 1)El constructor predefinido retorna un tipo void. 2)El constructor predefinido toma como parmetro un valor tipo void. 3)El constructor predefinido no toma parmetros.

40

javaHispano. Tu comunidad, tu lenguaje. 4)El constructor predefinido no se crea si la clase contiene algn constructor propio

Respuestas Respuesta 1) 4)super (99) Debido a que la clase Base tiene definido un constructor, el compilador no insertar el constructor predefinido con cero parmetros. Por consiguiente, llamar a super() causar un error. Una llamada a this() es un intento de llamar a un constructor con cero parmetros inexistente en la clase actual. La llamada a this(99) causar una referencia circular y causar un error en tiempo de compilacin. Respuesta 2) 4) no es retornado algn tipo de dato Debe ser bastante obvio de que ningn tipo de dato se retorna, as como por definicin los constructores no tienen tipos de datos Respuesta 3) 4)Se compilara y no mostrar nada al ejecutarse. Debido a que el mtodo Crowle retorna un tipo de dato no es un constructor, por consiguiente la clase se compilar y al ejecutarse el mtodo Crowle no se ejecutar pues no ha sido llamado-. Respuesta 4) 2)Error en tiempo de compilacin. Ocurre un error cuando la clase Severn intenta llamar al constructor con cero parmetros en la clase Base. Respuesta 5) 3)El constructor predefinido no toma parmetros. 4)El constructor predefinido no se crea si la clase contiene algn constructor propio

41

Tutorial para el examen de certificacin: SCJP 1.2

Otras Fuentes de este tema: Esta tema es cubierto en el Tutorial de Sun : http://java.sun.com/docs/books/tutorial/java/javaOO/constructors.html Richard Baldwin cubre este tema en http://www.Geocities.com/Athens/Acropolis/3797/Java042.htm#default constructor Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj3 Bruce Eckel Thinking In Java Captulo 4

42

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 4
Establecer los tipos de datos validos de retorno para cualquier mtodo, dada las declaraciones de todos lo mtodos relacionados con este o con la clase padre.

Nota de este objetivo


La frase del objetivo parece ser bastante obscura. Parece estar pidindote que entiendas la diferencia entre sobrecarga y sobrescritura. Para aprovechar mejor este objetivo necesitas una comprensin bsica sobre la sobrecarga y sobrescritura de mtodos. Esto se ve en la: Seccin 6: Orientacin a Objetos, sobrecarga y sobreescritura en tiempo de ejecucin

Mtodos en la misma clase


Si dos o ms mtodos en la misma clase tienen el mismo nombre, se dice que el mtodo esta sobrecargado. Puedes tener dos mtodos en una clase con el mismo nombre pero deben tener parmetros de diferente tipo y en diferente orden. Es el orden de los parmetros y los tipos de los mismos los que distinguen entre cualquiera de dos versiones de un mtodo sobrecargado a uno en especial. El tipo de dato de retorno no contribuye a la distincin entre mtodos. El cdigo siguiente generar un error en tiempo de compilacin, el compilador observa en amethod un intento por definir el mismo mtodo dos veces. Causa un error que dir algo como lo siguiente:
method redefined with different return type: void amethod(int) was int amethod(int) class Same{ public static void main(String argv[]){ Over o = new Over(); int iBase=0; o.amethod(iBase); } //Las siguientes definiciones generan un error al compilar public void amethod(int iOver){ System.out.println("Over.amethod"); } public int amethod(int iOver){ System.out.println("Over int return method"); return 0; }

43

Tutorial para el examen de certificacin: SCJP 1.2


}

El tipo de dato de retorno no contribuye a realizar la distincin entre un mtodo y otro.

Mtodos en una subclase.


Puedes sobrecargar un mtodo en una subclase. Todo lo que se requiere es que la nueva versin debe tener parmetros de diferente tipo y en diferente orden. Los nombres de los parmetros o el tipo de dato retornado por el mtodo no se toman en cuenta para la sobrecarga de mtodos. Si vas a sobrescribir un mtodo, por ejemplo para reemplazar su funcionalidad completamente en una subclase, la versin sobrescrita del mtodo debe tener la misma definicin que la versin de la clase base de la que esta descendiendo. Esto incluye el tipo de dato de retorno. Si creas un mtodo en una subclase con el mismo nombre y definicin pero retorna un tipo de dato distinto, generars el mismo mensaje de error que en el ejemplo anterior. Es decir:
method redefined with different return type: void amethod(int) was int amethod(int)

El compilador lo ve como un intento fallido por sobrecargar el mtodo en lugar de verlo como una sobrescritura del mtodo.

Preguntas Pregunta 1) Dada la siguiente definicin de clase:


public class Upton{ public static void main(String argv[]){

44

javaHispano. Tu comunidad, tu lenguaje.

} public void amethod(int i){} //Here }

Cules de las lneas siguientes son vlidas para ser colocadas despus del comentario //Here? 1) public int amethod(int z){} 2) public int amethod(int i,int j){return 99;} 3) protected void amethod(long l){ } 4) private void anothermethod(){} Pregunta 2) Dada la siguiente definicin de clase:
class Base{ public void amethod(){ System.out.println("Base"); } } public class Hay extends Base{ public static void main(String argv[]){ Hay h = new Hay(); h.amethod(); } }

Cul de los siguientes mtodo puede ser de la clase Hay para que compile y provoque que el programa muestre la cadena Hay ?

1) public int amethod(){ System.out.println("Hay");} 2) public void amethod(long l){ System.out.println("Hay");} 3) public void amethod(){ System.out.println("Hay");} 4) public void amethod(void){ System.out.println("Hay");} Respuestas Respuesta 1)

45

Tutorial para el examen de certificacin: SCJP 1.2 2) public int amethod(int i, int j) {return 99;} 3) protected void amethod (long l){} 4) private void anothermethod(){} La opcin 1 no compilara por dos razones. La primera es que obviamente exige que un entero sea retornado- y como podemos ver hace falta un return -. La otra es que es evidente un intento por redefinir un mtodo dentro de la misma clase. El cambio de nombre del parmetro de i a z no tiene efecto y un mtodo no puede ser sobrescrito dentro de la misma clase. Respuesta 2) 3) public void amethod(){ System.out.println("Hay");} La opcin 3 es una sobrescritura del mtodo de la clase Base, para alguna invocacin de esta versin se utilizarn cero parmetros La opcin 1 generar un error que indicar que se est intentando redefinir un mtodo con un diferente tipo de dato de retorno. Aunque la opcin 2 compilar, la llamada a amethod invocar el mtodo de la clase Base y la salida sea la cadena Base. La opcin 4 fue diseada para sorprender a aquellos con una cabeza llena de C/C++, en Java no hay tal cosa: la utilizacin de void para indicar que no hay parmetros.

Otras Fuentes de este tema: Jyothi Krishnan http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj4 En esta liga Jyothi sugiere que vayas al objetivo 19: http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html#obj19

46

javaHispano. Tu comunidad, tu lenguaje.

Seccin 2. Control de Flujo y Manejo de Excepciones.


Objetivo 1.
Escribir cdigo que use sentencias if y switch e identificar los tipos validos de argumentos para estas sentencias.

La sentencia if/else.
Ls sentencia if/else funciona en Java tal como podras esperar que funcione en otros lenguajes. las sentencias switch/case tienen unas peculiaridades. La sintaxis para la sentencia if/else es:
if(condicion tipo_boolean){ //si el boolean es verdadero se hace esto }else { //sino, se hace esto }

Java no tiene la palabra clave "then" como en Visual Basic. Las llaves son un indicador general en Java de una declaracin compuesta que permite ejecutar mltiples lneas de cdigo como resultado de alguna evaluacin. Esto se conoce como bloque de cdigo. La parte del "else" siempre es opcional. Una idiosincrasia de Java es que la sentencia if debe tomar un valor del tipo boolean. No puedes usar la convencin de C/C++ donde cualquier valor distinto de cero es verdadero y 0 es falso. As , en Java lo siguiente simplemente no compilar:
int k =-1; if(k){//no se compilar! System.out.println("do something"); }

Esto debido a que debes efectuar explcitamente una pregunta sobre la variable k que devuelva un valor tipo boolean, como en el ejemplo siguiente:
if(k == -1){ System.out.println("do something"); //compilacin OK! }

As como en C/C++ puedes no utilizar las llaves:

47

Tutorial para el examen de certificacin: SCJP 1.2

boolean k=true; if(k) System.out.println("do something");

Esto a veces es considerado un mal estilo de programacin, porque si modificas el cdigo despus para incluir declaraciones adicionales estas quedarn fuera del bloque condicional (qu solo abarca una lnea por no utilizar llaves) As:
if(k) System.out.println("do something"); System.out.println("also do this");

La segunda lnea siempre se ejecutar.

La Sentencia switch
La opinin de Peter van der Lindens sobre la sentencia switch se resume cuando dice: "Muerte a la sentencia switch" Este es un asunto al que le debes prestar atencin extra. El argumento de una sentencia switch debe ser un byte, char, short o un int. Puedes encontrar un ejercicio en el examen que use un float o un long como argumento en una sentencia switch. Una pregunta bastante comn parece estar sobre el uso de la sentencia break en el proceso descendente a travs de una sentencia switch. Aqu hay un ejemplo de este tipo de pregunta.
int k=10; switch(k){ case 10: System.out.println("ten"); case 20: System.out.println("twenty"); }

El sentido comn nos indicara que despus de ejecutar las instrucciones que siguen la primera sentencia case, y habindose encontrado con otra sentencia case, el compilador terminara su descenso a travs de la sentencia switch. Sin embargo, por razones mejor conocidas solo por los diseadores del lenguaje, una sentencia case solo se detiene cuando se encuentran con una sentencia break. Como resultado, en el ejemplo anterior las cadenas: "ten" y "twenty" son mostradas. Otra pequea peculiaridad que puede surgir en las preguntas es donde colocar la sentencia default.

48

javaHispano. Tu comunidad, tu lenguaje.

La clusula default no necesita ir al final de una sentencia case.

El lugar convencional para la sentencia default est al final de las opciones case. As normalmente el cdigo se escribir como sigue:
int k=10; switch(k){ case 10: System.out.println("ten"); break; case 20: System.out.println("twenty"); break; default: System.out.println("This is the default output"); }

Esta aproximacin refleja la manera en que piensa la mayora de las personas. Una vez que se han probado todas las posibilidades, se realiza la sentencia default. Sin embargo, el cdigo de una sentencia switch con la sentencia default hasta arriba es sintcticamente correcto, pero no aconsejable.
int k=10; switch(k){ default: //Coloca default hasta abajo y no ac System.out.println("This is the default output"); break; case 10: System.out.println("ten"); break; case 20: System.out.println("twenty"); break; }

Argumentos validos para las sentencias if y switch.


Como mencion anteriormente una sentencia if puede tomar solo un valor tipo boolean y una sentencia switch puede tomar solamente un byte, char, short o un int.

El operador ternario ?

49

Tutorial para el examen de certificacin: SCJP 1.2 Algunos programadores dicen que el operador ternario es til. Yo no considero para que. No se menciona especficamente en los objetivos as que por favor hganme saber si aparece en su examen.

Pregunta 1) Qu pasar cuando intentes compilar y ejecutar el siguiente cdigo?


public class MyIf{ boolean b; public static void main(String argv[]){ MyIf mi = new MyIf(); } MyIf(){ if(b){ System.out.println("The value of b was true"); } else{ System.out.println("The value of b was false"); } } }

1) Error en tiempo de compilacin: la variable b no fue inicializada 2) Error en tiempo de compilacin: el parmetro para la sentencia if debe evaluar a un
boolean

3) Error en tiempo de compilacin: no se puede crear y asignar un valor simultneamente a un boolean 4) Compilacin y ejecucin mostrando el segundo mensaje.

Pregunta 2) Qu pasar cuando intentes compilar y ejecutar este cdigo?


public class MyIf{ public static void main(String argv[]){ MyIf mi = new MyIf(); } MyIf(){ boolean b = false;

50

javaHispano. Tu comunidad, tu lenguaje.


if(b=false){ System.out.println("The value of b is"+b); } } }

1) Error en tiempo de ejecucin: un boolean no puede agregarse con el operador + 2) Error en tiempo de compilacin: el parmetro para la sentencia if debe evaluar a un
boolean

3) Error en tiempo de compilacin: no se puede crear y asignar un valor simultneamente a un boolean 4) Compilacin y ejecucin sin salida.

Pregunta 3) Qu pasar cuando intentes compilar y ejecutar este cdigo?


public class MySwitch{ public static void main(String argv[]){ MySwitch ms= new MySwitch(); ms.amethod(); } public void amethod(){ char k=10; switch(k){ default: System.out.println("This is the default output"); break; case 10: System.out.println("ten"); break; case 20: System.out.println("twenty"); break; } }

1) Ninguna de estas opciones 2) Error en tiempo de compilacin: el valor para el switch debe ser de tipo entero 3) Se Compilar y ejecutar mostrando "This is the default output" 4) Se Compilar y ejecutar mostrando "ten"

51

Tutorial para el examen de certificacin: SCJP 1.2 Pregunta 4) Qu pasar cuando intentes compilar y ejecutar el siguiente cdigo?
public class MySwitch{ public static void main(String argv[]){ MySwitch ms= new MySwitch(); ms.amethod(); } public void amethod(){ int k=10; switch(k){ default: //Put the default at the bottom, not here System.out.println("This is the default output"); break; case 10: System.out.println("ten"); case 20: System.out.println("twenty"); break; } }

1) Ninguna de estas opciones 2) Error en tiempo de compilacin: el valor para el switch debe ser de tipo entero 3) Se Compilar y ejecutar mostrando "This is the default output" 4) Se Compilar y ejecutar mostrando "ten"

Pregunta 5) De las siguientes lneas, cual podra usarse como parmetro para una declaracin switch? 1) byte b=1; 2) int i=1; 3) boolean b=false; 4) char c='c'; Respuestas Respuesta 1) 4) Compilacin y ejecucin mostrando el segundo mensaje.

52

javaHispano. Tu comunidad, tu lenguaje. Debido a que la variable boolean b se cre al nivel de clase, no necesita ser inicializada explcitamente y en cambio toma el valor predefinido de un boolean que es falso. Una sentencia if debe evaluar un valor boolean y as la variable b cumple este criterio. Respuesta 2) 4) Compilacin y ejecucin sin salida. Debido a que la variable b es un boolean no habr ningn error causado por la sentencia if. Si b fuera de cualquier otro tipo de dato hubiera ocurrido un error cuando intentaras realizar una asignacin en lugar de una comparacin. La expresin:
if(b=false)

es una asignacin y normalmente representa un error del programador. A menudo el programador tena en mente decir:
if (b==false)

Si el tipo de dato de b hubiera sido cualquiera menos boolean habra ocurrido un error al compilarse. El requisito para la sentencia if es que devuelva un boolean y debido a que:
if (b=false)

devuelve un boolean (false), esto es aceptable (pero inservible). Respuesta 3) 4) Se Compilar y ejecutar mostrando "ten" Respuesta 4) 1) Ninguna de estas opciones Debido a la falta de una sentencia break despus de la lnea:
System.out.println("ten");

la salida real ser: "ten" seguido de "twenty" Respuesta 5)

53

Tutorial para el examen de certificacin: SCJP 1.2 1) byte b=1; 2) int i=1; 4) char c='c'; Una sentencia switch puede tomar nicamente a un byte, char short o a un int como parmetro.

Otras Fuentes para este tema: El tutorial de Sun http://java.sun.com/docs/books/tutorial/java/nutsandbolts/while.html Richard Baldwin Cubre este tema en: http://www.Geocities.com/Athens/Acropolis/3797/Java026.htm#the if-else statement Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec2.html#obj5

54

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2.
Escribir cdigo que use todas las formas de ciclos incluyendo el etiquetado y desetiquetado, el uso de break y continue y conocer los valores tomados por las variables contadoras de los ciclos durante y despus de la ejecucin de cada ciclo.

La sentencia for
El mtodo ms comn para enciclar es usar la sentencia for. Como en C++ y a diferencia de C, la variable que controla el ciclo puede crearse e inicializarse dentro de la sentencia for. As
public class MyLoop{ public static void main(String argv[]){ MyLoop ml = new MyLoop(); ml.amethod(); } public void amethod(){ for(int K=0;K<5;K++){ System.out.println("Outer "+K); for(int L=0;L<5;L++) {System.out.println("Inner "+L);} } } }

Este cdigo iterara 5 veces en el ciclo interno por cada iteracin del ciclo externo. As la salida ser:
Outer Inner Inner Inner Inner inner Outer Inner Inner 0 0 1 2 3 4 1 0 2

Etc, etc. El sentencia for es el equivalente del ciclo for/next en Visual Basic. Debes tomar en cuanta que la sintaxis es:
for(inicializacin; expresin condicional; incremento)

55

Tutorial para el examen de certificacin: SCJP 1.2 La expresin condicional debe ser una expresin tipo boolean de una manera similar a la sentencia if. En el cdigo ejemplo sobre la sentencia for, esta fue seguida por un bloque del cdigo sealado por llaves. De la misma manera que un sentencia if no exige un bloque de cdigo, puedes tener una sentencia for que simplemente maneje una lnea, de esta manera:
for(int i=0;i<5;i++) System.out.println(i);

Nota que en ninguna de las versiones se termina la lnea del for con punto y coma. Si lo haces, el ciclo for solo iterara en esa lnea hasta que la condicin se cumpla y entonces el programa continuar en "lnea recta". No tienes que crear variable de inicializacin(como en este caso) dentro del ciclo for, pero si lo haces significar que la variable saldr del alcance en cuanto se termine el ciclo. Esto puede ser considerado una ventaja por lo que se refiere a mantener el alcance de las variables tan pequeo como sea posible.

Los ciclos while y do, nada inesperado.


Los ciclos while y do funcionan mucho ms de lo que esperaras de su equivalente en otros lenguajes. As un while se ejecutar cero o ms veces segn la condicin y el do se ejecutar una o ms veces. La sintaxis ara el ciclo while es:
while(condicin){ cuerpodelciclo; }

La condicin es una expresin tipo boolean parecida al de una sentencia if. De nuevo no puedes usar la convencin de C/C++ donde 0 es verdadero y cualquier otro valor es falso. De manera que podras crear un ciclo while de la siguiente manera:
while(i<4){ i++; System.out.println("Loop value is :"i); }

Nota que si la variable i valiera 4 o ms cuando se alcanzara la sentencia while no se producira ningn resultado. Por contraste un ciclo do siempre se ejecutar, al menos, una vez.

56

javaHispano. Tu comunidad, tu lenguaje. As con el cdigo siguiente siempre conseguirs por lo menos una ejecucin del cuerpo del ciclo no importando el valor de la variable i al entrar en el ciclo.
do{ System.out.println("value of : "+i); } while (i <4);

Muchos programadores intentan usar el ciclo for en lugar del ciclo while cuando pueden concentrar en una sola lnea la creacin, inicializacin, prueba e incremento del contador.

La sentencia goto, ciencia o religin?


Los diseadores de Java decidieron que ellos estaban de acuerdo con el gur de la programacin Edsger Dijkstra quien escribi un artculo famoso titulado "Goto considered harmful". Debido a que el uso indistinto de sentencias goto pueden dar como resultado un cdigo, cual espagueti, difcil de mantener, su uso se ha reducido y es considerado como un mal estilo de programacin. Hay situaciones donde sera til y para ayudar en esas situaciones Java ofrece las versiones etiquetadas y desetiquetadas de las palabras clave break y continue.

Break y Continue
Estas sentencias te permiten interrumpir condicionalmente ciclos. Sin embargo, no te permiten saltar a otra parte de programa. Es probable que el examen incluya este tema en la forma de un conjunto de ciclos anidados. Tienes que indicar que nmeros se mostrarn, al ejecutar el cdigo, antes de que termine el ciclo debido al mecanismo de la sentencia break. Este es un ejemplo de la clase de preguntas irritables que probablemente te encuentres en el examen.
public class Br{ public static void main(String argv[]){ Br b = new Br(); b.amethod(); } public void amethod(){ for(int i=0;i <3;i ++){ System.out.println("i"+i+"\n"); outer://<==Point of this example if(i>2){ break outer;//<==Point of this example

57

Tutorial para el examen de certificacin: SCJP 1.2


}//End of if for(int j=0; j <4 && i<3; j++){ System.out.println("j"+j); }//End of for }//End of for }//end of Br method }

Tienes que elegir que combinacin de letras se mostrar con la ejecucin del cdigo. A propsito el cdigo \n (en caso de que an no lo sepas) significa que se mostrar una lnea en blanco.

Saltar a una Etiqueta.


Es deseable a menudo, saltar de un ciclo interno a un ciclo externo dada una condicin. Puedes hacer esto etiquetando las sentencias break y continue. Una etiqueta es simplemente una palabra no reservada seguida de dos puntos. Poniendo el nombre de la etiqueta despus del break o continue tu cdigo saltar hasta la etiqueta. Esto es conveniente para hacer condicional una parte de un ciclo. Por supuesto, puedes hacer lo mismo con una sentencia if, pero una sentencia break es ms conveniente. No puedes saltar a otro ciclo o a otro mtodo pero una vez terminado el ciclo actual es muchas veces muy til.
La sentencia break abandona completamente el proceso del ciclo activo, la sentencia continue abandona nicamente el proceso de la iteracin activa del ciclo activo

Tomando en cuenta el siguiente cdigo:


public class LabLoop{ public static void main(String argv[]){ LabLoop ml = new LabLoop(); ml.amethod(); } public void amethod(){ outer: for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ if(j>1) //prueba con break en lugar de continue continue outer; System.out.println("i "+ i + " j "+j);

58

javaHispano. Tu comunidad, tu lenguaje.


} }//fin del for externo outer System.out.println("Continuing"); }//fin de amethod

Se mostrar lo siguiente:
i 0 j 0
i 0 j 1 i 1 j 0 i 1 j 1

Continuing

Si sustituyeras la sentencia continue por break, el contador i se detendra en cero ya que el proceso del ciclo externo se abandonara en lugar de simplemente continuar al siguiente incremento.

Pregunta 1) Que pasar cuando intentes compilar y ejecutar el siguiente cdigo en un mtodo?
for(int i=0;i<5;){ System.out.println(i); i++; continue; }

1) 2) 3) 4)

Error en tiempo de compilacin, sentencia for incorrecta. Error en tiempo de compilacin: continue dentro de un for Error en tiempo de ejecucin: sentencia continue no alcanzada. Se compilar y se ejecutar mostrando los valores del 0 al 4.

Pregunta 2) Qu pasar cuando intentes compilar y ejecutar el siguiente cdigo?


public class LabLoop{ public static void main(String argv[]){

59

Tutorial para el examen de certificacin: SCJP 1.2


LabLoop ml = new LabLoop(); ml.amethod(); mainmethod: System.out.println("Continuing"); } public void amethod(){ outer: for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ if(j>1) break mainmethod; System.out.println("i "+ i + " j "+j); } }//End of outer for

} }

1) i 0 j 0 i 0 j 1 Continuando 2) i 0 j 0 i 0 j 1 i 1 j 0 i 1 j 1 Continuando 3) Error en tiempo de Compilacin. 4) i 0 j 0 i 0 j 1 i 1 j 0 i 1 j 1 i 2 j 1 Continuando

Pregunta 3) Qu pasar cuando intentes compilar y ejecutar el siguiente cdigo?


public void amethod(){ outer: for(int i=0;i<2;i++){

60

javaHispano. Tu comunidad, tu lenguaje.


for(int j=0;j<2;j++){ System.out.println("i="+i + " j= "+j); if(i >0) break outer; }

} System.out.println("Continuing with i set to ="+i); } 1)Error en tiempo de compilacin. 2) i=0 j= 0 i=0 j= 1 i=1 j= 0 3) i=0 i=0 i=1 i=2 j= j= j= j= 0 1 0 0

4) i=0 j= 0 i=0 j= 1

Pregunta 4) Qu pasar cuando intentes compilar y ejecutar el siguiente cdigo?


int i=0; while(i>0){ System.out.println("Value of i: "+i); } do{ System.out.println(i); } while (i <2); 1) Value of i: 0 Seguido de 0 1 2 2) 0 1 2

61

Tutorial para el examen de certificacin: SCJP 1.2


3) Value of i: 0 Seguido de una secuencia de

0s

4) Mostrar una secuencia de 0s

Respuestas Respuesta 1) 4)Se compilar y se ejecutar mostrando los valores del 0 al 4. Esta es una versin un tanto extraa de la sentencia for, pero es totalmente valida. Respuesta 2) 3)
Error en tiempo de Compilacin.

No puede saltar arbitrariamente a otro mtodo, esto traeran consigo todo los males ya manifestados sobre la sentencia goto. Respuesta 3) 1)Error en tiempo de compilacin. Realmente esta no es una pregunta acerca del funcionamiento de break y continue. Este cdigo no se compilar porque la variable utilizada no existe fuera el ciclo for. Por lo tanto, la sentencia System.out.println, causar un error en tiempo de compilacin. Respuesta 4) 4)Mostrar una secuencia de 0s El ciclo while no ejecutar nada en absoluto si la condicin no es verdadera en su primera iteracin y debido a que no hay ningn incremento de algn valor en el ciclo do se ejecutar infinitamente. Otras Fuentes para este tema El tutorial de Sun http://java.sun.com/docs/books/tutorial/java/nutsandbolts/while.html Jyothi Krishnan http://www.geocities.com/SiliconValley/Network/3693/obj sec2.html#obj6

62

javaHispano. Tu comunidad, tu lenguaje.

Richard Baldwin http://www.Geocities.com/Athens/Acropolis/3797/Java026.htm#flow of control Bruce Eckel http://codeguru.earthweb.com/java/tij/tij0045.shtml#Heading131

63

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 3.
Escribir cdigo que haga un uso apropiado de las excepciones y las clusulas del manejo de excepciones (try, catch y finally), declarar mtodos y sobreescribir mtodos que lanzen excepciones. Las sentencias try y catch son parte del manejo de excepciones construido en Java. Ni C/C++ " ni Visual Basic tienen un equivalente directo a las excepciones construidas en Java. C++ soporta excepciones pero es de manera opcional, y Visual Basic soporta la captura de errores con On Error/Goto. Las excepciones en Java son construidas como parte del lenguaje. Por ejemplo si estas realizando instrucciones de Entrada y Salida (I/O) debes manipular excepciones. Puedes colocar por supuesto un manejador nulo que no haga nada. Lo siguiente es una pequea parte del cdigo que he acostumbrado a usar con Borland/Inprise JBuilder para detener temporalmente la salida de la consola y esperar que cualquier tecla sea presionada
import java.io.*; public class Try{ public static void main(String argv[]){ Try t = new Try(); t.go(); }//End of main public void go(){ try{ InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); br.readLine(); } catch(Exception e){ /*No se hace nada cuando ocurre la excepcin*/ } //End of try System.out.println("Continuing"); }//End of go }

En este caso no se hace nada cuando ocurre un error, pero el programador aun reconoce que puede ocurrir un error. Si quitas las clusulas try y catch el cdigo simplemente no compilar. El compilador sabe que los mtodos de I/O pueden causar excepciones y exige cdigo para manejar esas posibles excepciones.

Comparando con Visual Basic y C/C++


Esto es un poco ms riguroso que en Visual Basic o en C/C++ que te permite lanzar "sucia y rpidamente" programas que fingen que estn en un mundo donde los errores no

64

javaHispano. Tu comunidad, tu lenguaje. ocurren. No es exactamente una programacin esclavizada y disciplinada, las excepciones slo te animan persuasivamente a "hacer las cosas correctamente".

La Clusula finally
Una de las rarezas que probablemente te preguntarn en el examen, es bajo qu circunstancias se ejecuta la clusula finally de un bloque try/catch. La respuesta mas corta a esto es que la clusula finally casi siempre se ejecuta, incluso cuando podras pensar que no se ejecutara. Hemos dicho que, la trayectoria de ejecucin de las sentencias try/catch/finally es algo con lo que realmente necesitas jugar para convencerte de lo qu es lo que pasa bajo qu circunstancias.

la clusula finally de un bloque try/catch siempre se ejecutar, aun cuando haya cualquier sentencia de retorno en la parte try/catch

Uno de las pocas ocasiones donde la clusula finally no se ejecutar es si hay una llamada a:
System.exit(0);

El examen tiende a no intentar sorprenderte con esta excepcin a la regla. El examen es ms propenso a dar ejemplos que incluyan declaraciones de retorno para engaarte y hacerte pensar que el cdigo retornar sin ejecutar la sentencia finally. No te despistes, la clusula finally casi siempre se ejecutar. La clusula try/catch debe capturar los errores en el orden natural de su jerarqua. As, no puedes intentar capturar la excepcin Exception, que es mas general, antes de intentar capturar la excepcin IOException que es ms especfica.(NT: en otras palabras, debes de intentar capturar primero las ms especificas y luego las ms generales) El siguiente cdigo no se compilar:
try{ DataInputStream dis = new DataInputStream(System.in); dis.read(); }catch (Exception ioe) { }catch (IOException e) { //error en tiempo de compilacin }finally{}

65

Tutorial para el examen de certificacin: SCJP 1.2 Este cdigo generar un mensaje de error en tiempo de compilacin: IOException nunca se alcanzar.

Sobrescribiendo mtodos que lanzan excepciones


Un mtodo sobrescrito en una subclase solo puede lanzar excepciones declaradas en la clase padre o excepciones que sean hijas de las excepciones declarados en la clase padre. Esto es slo valido para mtodos sobrescritos y no para mtodos sobrecargados. As, si un mtodo tiene exactamente el mismo nombre y argumentos puede lanzar nicamente excepciones declaradas en la clase padre, o excepciones que son hijos de excepciones de la declaracin de la clase padre. No obstante puede lanzar ninguna o pocas excepciones. As el ejemplo siguiente no se compilar:
import java.io.*; class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ //No se compilara, la excepcin que se intenta lanzar no esta //en la versin del mtodo amethod en la clase Padre(Base) public static void amethod()throws IOException{} }

Si fuera el mtodo de la clase padre el que estuviera lanzando a IOException y el mtodo en la clase hijo el que estuviera lanzando a FileNotFoundException el cdigo si compilara(NT: debido a que FileNotFoundException es subclase de IOException). De nuevo, recuerda que esto slo se aplica a los mtodos sobrescritos, no hay ninguna regla similar para los mtodos sobrecargados. Un mtodo sobrescrito en una subclase tambin puede lanzar excepciones.

Pregunta 1)

66

javaHispano. Tu comunidad, tu lenguaje.

Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


import java.io.*; class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ public static void main(String argv[]){ ExcepDemo e = new ExcepDemo(); } public static void amethod(){} protected ExcepDemo(){ try{ DataInputStream din = new DataInputStream(System.in); System.out.println("Pausing"); din.readChar(); System.out.println("Continuing"); this.amethod(); }catch(IOException ioe) {} } }

1)Error en tiempo de compilacin causado por el constructor protegido. 2)Error en tiempo de compilacin causado por que amethod ha declarado excepciones. 3)Error al ejecutar: amethod no ha declarado excepciones. 4)Se compilara y se ejecutara mostrando: Pausing y Continuing despus de que una tecla es pulsada. Pregunta 2) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?
import java.io.*; class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ public static void main(String argv[]){ ExcepDemo e = new ExcepDemo(); } public static void amethod(int i)throws IOException{}

67

Tutorial para el examen de certificacin: SCJP 1.2

private ExcepDemo(){ try{ DataInputStream din = new DataInputStream(System.in); System.out.println("Pausing"); din.readChar(); System.out.println("Continuing"); this.amethod(); }catch(IOException ioe) {} } }

1)Error en tiempo de compilacin causado por el constructor privado. 2)Error en tiempo de compilacin: amethod ha declarado excepciones que no estn en la versin de la clase base. 3)Error al ejecutar: amethod ha declarado excepciones que no estn en la versin de la clase base. 4)Se compilara y se ejecutara mostrando: Pausing y Continuing despus de que una tecla es pulsada.

Pregunta 3) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


import java.io.*; class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ public static void main(String argv[]){ ExcepDemo e = new ExcepDemo(); } public static void amethod(int i)throws IOException{} private boolean ExcepDemo(){ try{ DataInputStream din = new DataInputStream(System.in); System.out.println("Pausing"); din.readChar(); System.out.println("Continuing"); this.amethod(); return true; }catch(IOException ioe) { }finally{ System.out.println("finally"); }

68

javaHispano. Tu comunidad, tu lenguaje.


return false; } }

1)Se compilara y se ejecutara sin mostrar algo. 2)Mostrando: Pausing, Continuing y Finally 3)Error al ejecutar: amethod ha declarado excepciones que no estn en la versin de la clase base. 4)Se compilara y se ejecutara mostrando: Pausing y Continuing despus de que una tecla es pulsada.

Pregunta 4) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


import java.io.*; class Base{ public static void amethod()throws FileNotFoundException{} } public class ExcepDemo extends Base{ public static void main(String argv[]){ ExcepDemo e = new ExcepDemo(); } public boolean amethod(int i){ try{ DataInputStream din = new DataInputStream(System.in); System.out.println("Pausing"); din.readChar(); System.out.println("Continuing"); this.amethod(); return true; }catch(IOException ioe) { }finally{ System.out.println("Doing finally"); } return false; } ExcepDemo(){ amethod(99); } }

69

Tutorial para el examen de certificacin: SCJP 1.2

1)Error en tiempo de compilacin: amethod no lanza FileNotFounfException 2)Se compila, se ejecuta y muestra Pausing y Continuing 3) Se compila, se ejecuta y muestra Pausing ,Continuing y Doing finally 4)Error en tiempo de compilacin, la clusula finally nunca se alcanza. Respuestas Respuesta 1) 4)Se compilara y se ejecutara mostrando: Pausing y Continuing despus de que una tecla es pulsada. Un mtodo sobrescrito en una subclase no debe lanzar Excepciones no lanzadas en la clase base. En el caso del mtodo amethod este no lanza ninguna excepcin y en consecuencia compilar, as sin alguna indicacin. No hay razn alguna por la que un constructor no pueda protegerse. Respuesta 2) 4)Se compilara y se ejecutara mostrando: Pausing y Continuing despus de que una tecla es pulsada. En este versin amethod se ha sobrecargado de manera que no hay ninguna restriccin sobre qu excepciones pueden o no ser lanzadas. Respuesta 3) 1)Se compilara y se ejecutara sin mostrar algo. OK, aqu me he salido un poco fuera del tema. Observa que lo que antes era un constructor ahora tiene un valor del retorno. Esto lo convierte en un mtodo ordinario y por lo tanto no se llama cuando se crea una instancia de la clase. Respuesta 4) 3) Se compila, se ejecuta y muestra Pausing ,Continuing y Doing finally La clusula finally siempre se ejecuta Otras Fuentes para este tema Este tema es cubierto en el Tutorial de SUN http://java.sun.com/docs/books/tutorial/essential/exceptions/definition.html Richard Baldwin cubre este tema en: http://www.geocities.com/Athens/Acropolis/3797/Java030.htm 70

javaHispano. Tu comunidad, tu lenguaje. y http://www.geocities.com/Athens/Acropolis/3797/Java056.htm Jyothi Krishnan en http://www.geocities.com/SiliconValley/Network/3693/obj_sec2.html#obj7 Bruce Eckel Thinking in Java Captulo 9)

71

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 3. Recolector de basura Garbage CollectorObjetivo 1.


Exponer el comportamiento que se garantiza por el sistema de recoleccin de basura y escribir cdigo que explcitamente haga objetos elegibles para la recoleccin.

Por qu querras utilizar el recolector de basura?


Puedes ser un programador de Java muy experimentado y nunca haber tenido que familiarizarte con los detalles del recolector de basura. Incluso la expresin recoleccin de basura es un poco rara. En este contexto significa la liberacin de memoria que se ha asignado y que ya ha sido usada por el programa. Cuando ya no se necesita una parte de la memoria asignada sta puede considerarse como basura, es decir algo que ya no se necesita; y que simplemente est desordenando espacio til. Una de las grandes cualidades aclamadas de Java es que no tienes que preocuparte por la recoleccin de basura. Si vienes de programar con Visual Basic puede parecerte absurdo que algn sistema, por si mismo, no cuide este detalle. En C/C++ el programador tiene que seguir, de forma manual, el rastro la asignacin y desasignacin de la memoria. Como resultado de esto, las "fugas de memoria" son una gran fuente de errores difciles de rastrear. sta es una de las razones por las que algunas versiones de aplicaciones de Microsoft como Word o Excel, se detienen apenas comienzan a ejecutarse. Las fugas de memoria a la larga, finalmente hacen que el sistema entero se cuelgue y que te veas en la necesidad de pulsar ese gran interruptor luminoso. En alguna parte, en esos centenares de miles de lneas de cdigo en C++, un programador asign un bloque de memoria pero se le olvido asegurarse de liberarla.

Java y el recolector de basura.


A diferencia de C/C++, Java libera automticamente las referencias que no se estn utilizando. No tienes que pasar por el trauma de buscar asignaciones de memoria que nunca son liberadas y por consiguiente, no necesita saber cmo asignar cmo saber el tamao de un tipo de datos para asegurar la compatibilidad de la plataforma. As qu Por qu querras conocer mas los detalles del recolector de basura? Dos respuestas saltan a mi mente, una es aprobar el examen y la otra es comprender lo que ocurre en circunstancias extremas. Por ejemplo, si escribes cdigo que genere nmeros muy grandes de objetos o de variables te puede ser til saber cuando se liberan las referencias. Si lees algn newsgroups vers a personas informando en ocasiones de ciertas aplicaciones Java que agotan los recursos y hacen que todo se caiga. Esto no estaba en el folleto del SUN cuando lanzaron Java.

72

javaHispano. Tu comunidad, tu lenguaje. Siguiendo la filosofa de la recoleccin de basura automtica, puedes sugerir o animar que la JVM realice la recoleccin de basura, pero no la puedes forzar.

Permteme remarcar el punto, no puedes forzar la ejecucin de la recoleccin de basura, slo puedes sugerirla.

A primera vista el termino finalizacin me suena un poco como a los destructores en C++ usados para limpiar los recursos antes de que se destruya un objeto. La diferencia es qu en Java los recursos internos no necesitan ser liberados durante la finalizacin porque el recolector de basura cuida la asignacin de memoria. Sin embargo si tienes recursos externos como un archivo de informacin, puedes usar la finalizacin para liberarlos. Escribir ejercicios o practicar con el recolector de basura es un poco complejo ya que no hay manera de conseguir cdigo que indique cuando est disponible para la recoleccin de basura. No puedes escribir un fragmento de cdigo con una sintaxis como la siguiente:
if(EligibleForGC(Object){ //cdigo no real System.out("Ready for Garbage"); }

Debido a esto solo tienes que aprender las reglas. Una vez que una variable no es referenciada en mucho tiempo est disponible para ser recolectada por el recolector de basura. Puedes sugerir la ejecucin del recolector de basura con el mtodo System.gc(), pero esto no garantiza que se ejecutar inmediatamente. Las variables locales en los mtodos pierden su alcance cuando el mtodo que las ocupa termina. A partir de ese momento esos mtodos son elegibles para el recolector de basura. Cada vez que el mtodo vuelve a estar en el alcance del programa las variables locales se vuelven a crear.

73

Tutorial para el examen de certificacin: SCJP 1.2 Pregunta 1) Cual de las siguientes lneas tiene la sintaxis correcta para sugerir que la JVM ejecute la recoleccin de basura?
1) System.free(); 2) System.setGarbageCollection(); 3) System.out.gc(); 4) System.gc();

Pregunta 2) Qu cdigo puedes escribir para asegurarte que las variables tipo int son recolectadas en un punto particular en este cdigo?
public class Rub{ int i=1; int j=2; int k=3; public static void main(String argv[]){ Rub r = new Rub(); r.amethod(); } public void amethod(){ i=0; j=0; k=0; } }

1) System.gc(); 2) System.free(); 3) Fijar el valor de cada variable int a null. 4) Ninguno de los anteriores.

Respuestas Respuesta 1)
4) System.gc();

Respuesta 2) 4) Ninguno de los anteriores.

74

javaHispano. Tu comunidad, tu lenguaje. nicamente puedes sugerir la ejecucin del recolector de basura, por consiguiente no puedes estar seguro que se ejecutar en algn punto en particular de tu cdigo. Otras Fuentes para este tema Jyothi Krishnan en http://www.geocities.com/SiliconValley/Network/3693/obj_sec3.html#obj8

75

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 4. Fundamentos del lenguaje.


Objetivo 1.
Identificar las declaraciones correctas para la construccin de paquetes, conocer la sentencia import, la declaracin de clases (todas las formas para incluir clases internas), conocer la declaracin e implementacin de interfaces (por ejemplo java.lang.Runnable u otra interfase descrita en el examen), declaracin de mtodos (incluyendo el mtodo main que se usa para comenzar la ejecucin de una clase), las declaraciones de variables e identificadores.

Nota sobre este objetivo


La frase de este objetivo es un poco extraa. Parece estar pidindote que entiendas donde, cmo y por qu puedes usar la sentencia import y package, donde debes colocar la declaracin de una interface y las declaraciones de las variables.

La sentencia package
La palabra package implica una coleccin de clases, algo parecido a una librera. En el uso, un paquete es un poco semejante a un directorio. Si pones una declaracin de un paquete en un archivo ste ser slo visible a otras clases en el mismo paquete. Puedes poner un comentario antes de la declaracin del paquete pero nada ms. Puedes encontrar preguntas del examen en donde pongan una sentencia import antes de la declaracin del paquete.
//Puedes colocar un comentario antes de la sentencia package package MyPack; public class MyPack{}

Lo siguiente causar un error:


import java.awt.*; //Error: colocar una sentencia import antes de la declaracin //del paquete causar un error al compilar. package MyPack; public class MyPack{}

Si un archivo fuente tiene una sentencia package, sta debe ponerse antes de cualquier otra declaracin aparte de los comentarios.

La sentencia package puede incluir la anotacin punto para indicar la jerarqua del paquete. As el siguiente cdigo compilar sin el error:
package myprogs.MyPack;

76

javaHispano. Tu comunidad, tu lenguaje.


public class MyPack{}

Recuerda que si no pones una sentencia package al inicio del archivo fuente, se considerar que ste forma parte del paquete predefinido que corresponde al directorio actual.

La sentencia import
La sentencia import debe ir despus de cualquier sentencia package y antes de cualquier otra lnea de cdigo. La sentencia import no puede ir dentro de las clases, ni despus de la declaracin de la clase o en cualquier otra lugar. La sentencia import te permite usar una clase directamente con su nombre en lugar de especificarla totalmente incluyendo el nombre completo del paquete al que pertenece. Un ejemplo de esto es que a la clase java.awt.Button normalmente se le referencia simplemente como Button, pero para ello requieres haber puesto al inicio del archivo fuente la siguiente lnea:
import java.awt.*;

Toma en cuenta que an usando la declaracin completa de la clase no se afecta el desempeo ni se cambia el tamao del archivo .class generado.

Clases y la declaracin de clases internas


Un archivo puede tener nicamente una clase con modificador public. Si intentas crear un archivo con ms de una clase pblica el compilador te indicar un error especfico. Un archivo puede contener mltiples clases no pblicas, pero ten presente que esto generara distintos archivos .class separados por cada clase. Las clases internas se introdujeron con el JDK 1.1 La idea es permitir la definicin de una clase dentro de otra, para que sta pueda ser definida dentro de un mtodo y para la creacin de clases internas annimas. Esto tiene algunos efectos interesantes, particularmente en la visibilidad. Lo siguiente es un ejemplo sencillo de una clase interna:
class Outer{ class inner{} }

Esto produce la generacin de archivos .class con los nombres:

77

Tutorial para el examen de certificacin: SCJP 1.2


Outer.class Outer$Inner.class

La definicin de la clase interna es slo visible dentro del contexto de la existente clase Exterior. As el siguiente cdigo causar un error cuando se compile:
class Outer{ class Inner{} } class Another{ public void amethod(){ Inner i = new Inner(); } }

De modo que la clase Another no se podra crear, ya que, en ese contexto la clase inner no existe. sta slo puede existir en el contexto de una instancia de la clase Outer. As, el siguiente cdigo se compilar sin problemas ya que s esta instanciando la clase Inner dentro del mbito de la clase Outer.
class Outer{ public void mymethod(){ Inner i = new Inner(); } public class Inner{} }

Pero que pasa si el contexto de la instancia Outer no existe. Para entender mejor como conseguir lo anterior, pensemos como podemos lograr el efecto anterior utilizando la palabra clave this. Podras cambiar la lnea que crea la instancia por lo siguiente:
Inner i = this.new Inner();

As, si necesitas crear una instancia de la clase Inner en un mtodo esttico o en alguna otra parte donde no tenga mbito el objeto, puedes usar la palabra clave new como un mtodo que pertenece a una clase exterior.
class Outer{ public class Inner{} }

78

javaHispano. Tu comunidad, tu lenguaje.


class another{ public void amethod(){ Outer.Inner i = new Outer().new Inner(); } }

A pesar de mis locas explicaciones, encuentro poco intuitiva esta sintaxis y hasta yo me olvido de ella cinco minutos despus de aprendrmela. Es muy probable que encuentres preguntas referentes a esto en el examen, as que prstale bastante atencin.

Puedes acceder a una clase interna utilizando el siguiente cdigo: Outer.Inner i = new Outer().new Inner();

Uno de los beneficios de las clases internas es que una clase interna generalmente consigue acceso a los campos la clase que lo contiene(o una externa) Al contrario de una clase externa, una clase interna puede ser privada o esttica. Los examinadores pueden hacer preguntas molestas como "Puede una clase interna ser esttica o privada?". Haciendo esttica una clase interna, sta tiene algunos efectos interesantes con la manera en que se tienen acceso a los campos o miembros de la clase que la contiene. El efecto de hacer estticos los recursos se refleja en que slo hay una instancia de cualquier variable, no importa cuntas instancias se creen de la clase externa. En esta situacin Cmo puede la clase interna esttica saber qu variables puede acceder de su clase externa no esttica?. Por supuesto la respuesta es que no lo puede saber, y as una clase interna esttica no puede acceder variables de instancia de la clase que la contiene. Por supuesto, los mtodos de una clase interna esttica pueden acceder a cualquier campo o miembro esttico de la clase que lo contiene pero siempre ser nicamente a una sola instancia de cualquiera de esos campos.

Clases internas declaradas dentro de mtodos


Las clases internas se pueden crear dentro de los mtodos. Esto es algo que las herramientas de desarrollo de aplicaciones como JBuilder de Borland hacen constantemente cuando generan un manejador de Eventos. Aqu hay un ejemplo de dicho cdigo generado automticamente: 79

Tutorial para el examen de certificacin: SCJP 1.2

buttonControl1.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(MouseEvent e) { buttonControl1_mouseClicked(e); } });

Fjate en la palabra clave new que se encuentra justo despus del primer parntesis. Esta indica que una clase interna annima(sin nombre) est definindose dentro del mtodo addMouseListener. Esta clase normalmente podra definirse con un nombre que podra hacerla ms fcil de leer, pero cuando ese fragmento de cdigo no se utiliza para algn otro proceso en cualquier otra parte, darle un nombre no ayuda mucho. Si creas tal cdigo de manera manual, es fcil confundirte por el nmero de niveles de las llaves y parntesis. Observa cmo la estructura completa finaliza con punto y coma, ya que es realmente ah en donde finaliza la llamada al mtodo. Como podras suponer una clase annima no puede tener un constructor. Mralo de esa manera, un constructor es un mtodo sin valor de retorno y con el mismo nombre de la clase. Upss! Nosotros estamos hablando de clases sin nombres. Una clase annima puede heredar otra clase o implementar una nica interface. Este lmite peculiar no parece ser tomado en cuenta en el examen.

Visibilidad de campos para clases definidas dentro de un mtodo


Una clase definida dentro de un mtodo puede acceder slo a campos o miembros del mtodo que la contiene si stos se han definido con el modificador final. Esto se debe a que las variables definidas dentro de un mtodo normalmente se consideran variables automticas; es decir, slo existen mientras el mtodo se est ejecutando. Los Campos o miembros definidos dentro de una clase creada dentro de un mtodo duran mas que el mtodo que la contiene.

Una clase definida dentro de un mtodo solo puede acceder a campos con el modificador final del mtodo que la contiene

Debido que una variable con modificador final no puede ser cambiada por la JVM puedes estar seguro que el valor permanecer constante aun despus de que el mtodo exterior ha dejado de ejecutarse. Es muy probable que encuentres preguntas referentes a esto en el examen, incluso preguntas que cuestionen el estado de las variables pasadas como parmetros al mtodo.

80

javaHispano. Tu comunidad, tu lenguaje.

Creando una interface


Las interfaces son la manera en que Java maneja la ausencia de la herencia mltiple. Curiosamente Visual Basic tiene la palabra reservada interface y maneja el concepto de manera similar a Java. El tema de las interfaces es conocido en ocasiones como programacin por contacto. Una interface se utiliza a travs de la palabra clave implements. As, una clase puede declararse de la siguiente manera:
class Malvern implements Hill,Well{ public }

Pregunta 1) Dado el siguiente cdigo:


public class FinAc{ static int l = 4; private int k=2; public static void main(String argv[]){ FinAc a = new FinAc(); a.amethod(); } public void amethod(){ final int i = 99; int j = 6; class CInMet{ public void mymethod(int q){ //Here }//fin de mymethod }//fin de CInMet CInMet c = new CInMet(); c.mymethod(i);

81

Tutorial para el examen de certificacin: SCJP 1.2


}//fin de amthod }

Cuales de las siguientes variables son visibles en la lnea marcada con el comentario //Here? 1)l 2)k 3)i 4)j

Pregunta 2) Cuales de los siguientes fragmentos de cdigo compilarn correctamente?


1) //A Comment import java.awt.*; class Base{}; 2) import java.awt.*; package Spot; class Base(); 3) //Another comment package myprogs.MyPack; public class MyPack{} 4) class Base{} import java.awt.*; public class Tiny{}

Pregunta 3) Cuales de las siguientes afirmaciones son verdaderas? 1)Una clase interna puede definirse como esttica 2)Una clase interna no puede ser defina como privada 3)Una clase annima puede tener slo un constructor 4)Una clase interna puede heredar otra clase

82

javaHispano. Tu comunidad, tu lenguaje. Pregunta 4) Desde cdigo que no tenga activa la referencia this, Como puedes crear una instancia de una clase interna?
1)Outer.Inner i = new Outer().new Inner(); 2)Sin una referencia this una clase interna no puede ser creada 3)Outer.Inner i = Outer().new new Inner(); 4)Outer i = Outer.new().Inner();

Respuestas Respuesta 1) 1) l 2) k 3) i Una clase definida dentro de un mtodo solo puede ver campos con el modificador final desde el mtodo que la contiene. Sin embargo, tambin puede ver los campos de la clase que contiene al mtodo que la contiene a ella, incluyendo campos privados. El campo j no se defini como final. Respuesta 2)
1) //A Comment import java.awt.*; class Base{}; 3) //Another comment package myprogs.MyPack; public class MyPack{}

La declaracin de un paquete debe ser la primera lnea de cdigo en un archivo (aparte de los comentarios). Una declaracin import debe estar despus de cualquier declaracin de un paquete y antes de cualquier otra lnea de cdigo. Respuesta 3) 1)Una clase interna puede definirse como esttica 4)Una clase interna puede heredar otra clase Las clases annimas no pueden tener un constructor. Las clases internas pueden definirse como privadas. Respuesta 4)

83

Tutorial para el examen de certificacin: SCJP 1.2 1)Outer.Inner i = new Outer().new Inner();

Otras Fuentes para este tema: El Tutorial de SUN http://java.sun.com/docs/books/tutorial/java/more/nested.html Richard Baldwin http://www.Geocities.com/Athens/7077/Java094.htm y tambin http://www.Geocities.com/Athens/7077/Java095.htm Jyothi Krishnan http://www.geocities.com/SiliconValley/Network/3693/obj_sec4.html#obj9 Un Tutorial sobre paquetes http://v2ma09.gsfc.nasa.gov/JavaPackages.html Especificaciones sobre interfaces en Java http://java.sun.com/docs/books/jls/html/9.doc.html#238680

84

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2.
Declarar la correspondencia entre los valores del arreglo pasado como argumento al mtodo main y los argumentos de la lnea de comandos. Nota: Este tema por s solo difcilmente amerita ser tomado como un objetivo. Este objetivo puede sorprender al programador ms experimentado en C/C++ ya que el primer elemento del arreglo argv[] es la primera cadena despus del nombre del programa en la lnea de comandos. As si un programa se ejecutara como sigue:
java myprog myparm

El elemento argv[0] contendra "myparm". Si vienes de programar en C/C++ podras esperar que el contenido fuera "java". Java no contiene una opcin equivalente a Option Base de Visual Basic y, en consecuencia, los arreglos siempre empezarn desde el elemento cero. Veamos el siguiente cdigo:
public class MyParm{ public static void main(String argv[]){ String s1 = argv[1]; System.out.println(s1); } }

He asignado el argumento 1 a un String slo para resaltar que argv es un arreglo de String's. Si ejecutas este programa de la manera siguiente:
java MyParm hello there

Se mostrar there, y no hello o MyParm

Pregunta 1)

85

Tutorial para el examen de certificacin: SCJP 1.2 Dado el siguiente mtodo main en una clase llamada cycle:
public static void main(String bicycle[]){ System.out.println(bicycle[0]); }

y una llamada desde la lnea de comandos como la siguiente:


java Cycle one two

Cul ser la salida? 1) Ninguna de estas opciones 2) Cycle 3) one 4) two Pregunta 1) Cmo puedes recuperar los valores pasados desde la lnea comandos al mtodo main? 1) usando el mtodo System.getParms() 2) asignando un elemento del argumento a un String 3) asignando un elemento del argumento a un arreglo de caracteres 4) ninguna de estas opciones

Respuestas Respuesta 1) 3) one Respuesta 2) 2) asignando un elemento del argumento a un String

Otras Fuentes para este tema: Este tema es cubierto en el tutorial de SUN en: http://java.sun.com/docs/books/tutorial/essential/attributes/cmdLineArgs.html

86

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 3.
Identificar todas las palabras reservadas del lenguaje. Nota en este objetivo: Puedes asimilar fcilmente este objetivo en base a aprender las palabras reservadas frecuentemente menos utilizadas y asegurndote no tomar en cuenta a "falsos friends" de otros lenguajes que puedes llegar a saber, particularmente C/C++. El examen pone nfasis especial en el reconocimiento de las palabras reservadas. Reconocers la mayora de la palabras reservadas de Java conforme uses el lenguaje, pero en el uso personal del lenguaje raramente utilizamos las excepciones, y las palabras reservadas que podran venir en el examen. Ejemplos de las palabras reservadas ms raramente utilizadas (indudablemente para un principiante) son:

volatile transient native


Palabras reservadas

abstract char double for int package static throws

boolean class else goto * interface private super transient

break const * extends if long protected switch try

byte continue final implements native public void

case default finally import new return volatile

catch do float instanceof null short throw while

synchronized this

Las palabras con asteriscos son reservadas y actualmente no son utilizadas. Observa que todas las palabras reservadas estn en minsculas, as for es una palabra reservada pero FOR no la es. Hay un debate acerca de que si null es una palabra reservada, pero sugiero que para los propsitos del examen asumas que si la es.

NT: El autor utiliza esa expresin para referirse a la confusin que en ocasiones produce la palabra friend, la cual es palabra reservada en C++, pero no en Java.

87

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 1) Cules de las siguientes son palabras reservadas de Java?


1) double 2) Switch 3) then 4) instanceof

Pregunta 2) Cules de las siguientes no son palabras reservadas de Java?


1)volatile 2)sizeOf 3)goto 4)try

Respuestas Respuesta 1)
1) double 4) instanceof

Nota que la letra mayscula S en switch hace que sta no sea una palabra reservada y la palabra then es parte de Visual Basic pero no de Java. Respuesta 2) 2)sizeOf

88

javaHispano. Tu comunidad, tu lenguaje. Esta es una palabra reservada en C/C++ para determinar el tamao de un dato primitivo para una plataforma en particular. Debido a que los datos primitivos tienen el mismo tamao en todas las plataformas en Java sta palabra reservada no se necesita. Otras Fuentes para este tema Michael Thomas http://www.michael-thomas.com/java/JCP_Keywords.htm

89

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 4.
Conocer el efecto de usar una variable o un elemento de un arreglo de cualquier tipo cuando no se le ha hecho alguna asignacin explicita.

Variables
Podras aprender a programar en Java sin realmente entender la importancia que representa este objetivo, pero ste representa conocimiento valioso para el mundo real. Esencialmente a una variable de nivel de clase siempre se le asignar un valor predefinido y a una variable miembro (una variable contenida dentro de un mtodo) no se le asignar un valor predefinido. Si intentas acceder a una variable sin asignar generars un error. Por ejemplo:
class MyClass{ public static void main(String argv[]){ int p; int j = 10; j=p; } }

Este cdigo producir el siguiente error:


"error variable p might not have been assigned"

Esto puede verse como un cambio bienvenido de la tendencia de C/C++ de darle bastante cuerda a una variable sin asignar dejando un valor arbitrario en p. Si p se hubiera definido al nivel de clase se le habra asignado su valor predefinido y no se habra generado algn error.
class MyClass{ static int p; public static void main(String argv[]){ int j = 10; j=p; System.out.println(j); } }

El valor predefinido para un entero es 0, as el cdigo anterior mostrar 0. El valor predefinido para los tipos de datos numricos es cero, para un boolean es false y una referencia a un objeto es el nico tipo de datos que tiene como valor predefinido null.

90

javaHispano. Tu comunidad, tu lenguaje.

Antes de la inicializacin de los arreglos, donde quiera que sean creados, estos siempre son fijados para contener sus valores predefinidos.

Arreglos
Aprender esta parte del objetivo requiere comprender una sencilla regla. El valor de los elementos de un arreglo de cualquier tipo base siempre se inicializar con un valor predefinido, dondequiera que se defina el arreglo. No importa si el arreglo se define a nivel de clase o mtodo, a los valores del arreglo siempre se le pondrn sus valores predefinidos. Una pregunta que puedes hacerte es Qu contendr un elemento en particular de un arreglo sin asignar?. A menos que el arreglo sea de objetos, la respuesta ser distinta de null.

Pregunta 1) Dado el siguiente cdigo, Qu contendr el elemento b[5]?


public class MyVal{ public static void main(String argv[]){ MyVal m = new MyVal(); m.amethod(); } public void amethod(){ boolean b[] = new boolean[5]; } }

1) 0 2) null

91

Tutorial para el examen de certificacin: SCJP 1.2 3) "" 4) Ninguna de estas opciones

Pregunta 2) Dado el siguiente cdigo, Qu contendr el elemento 1 del arreglo mycon?


MyCon(){ int[] mycon= new int[5]; }

1) 0 2) null 3) "" 4) Ninguna de estas opciones

Pregunta 3) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


public class MyField{ int i=99; public static void main(String argv[]){ MyField m = new MyField(); m.amethod(); } void amethod(){ int i; System.out.println(i); } }

1)Se mostrar 99 2)Se mostrar 0 3)Se generar un error al compilar 4)Se generar un error al ejecutar

Pregunta 4) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


public class MyField{

92

javaHispano. Tu comunidad, tu lenguaje.


String s; public static void main(String argv[]){ MyField m = new MyField(); m.amethod(); } void amethod(){ System.out.println(s); } }

1)Error al compilar: s no ha sido inicializada 2)Error al ejecutar: s no ha sido inicializada 3)Salida en blanco 4)Se mostrar null Respuestas Respuesta 1) 4) Ninguna de estas opciones Atencin en este punto. Los elementos de un arreglo comienzan a numerarse desde 0, por consiguiente, para ste arreglo, no hay un elemento 5. Si intentas ejecutar:
System.out.println(b[5])

Generars una excepcin. Respuesta 2) 1)0 Un constructor acta de manera parecida a cualquier otro mtodo; as, un arreglo de enteros ser inicializado conteniendo ceros dondequiera que sea creado. Respuesta 3) 3)Se generar un error al compilar Generars un error al compilar el cdigo indicando que la variable i no ha sido inicializada, la variable de nivel de clase i es un caso extrao, ya que es ensombrecida por su versin en el nivel del mtodo. Las variables de nivel de mtodo no obtienen ninguna inicializacin por omisin. Respuesta 4) 4)Se mostrar null 93

Tutorial para el examen de certificacin: SCJP 1.2

Una variable creada en el nivel de clase siempre tendr un valor por omisin. El valor por omisin para una referencia a un objeto es null y el mtodo toString implcitamente llamado con System.out.println mostrar null.
Otras Fuentes para este tema: Este tema es cubierto ligeramente en el Tutorial de SUN en: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/vars.htmll Richard Baldwin cubre el tema en: http://www.geocities.com/Athens/Acropolis/3797/Java020.htm#variables Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec4.html#obj12

94

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 5.
Definir el rango de todos los tipos de datos primitivos, declarar valores literales para Strings y todos los tipos primitivos usando todos los formatos permitidos, conocer las bases numricas y sus representaciones. Nota en este objetivo ste es uno de los ligeramente molestos, pero bastante fcil, objetivos a cubrir. Puedes escribir una gran cantidad de cdigo Java sin conocer el rango de los tipos primitivos pero familiarizarte con ellos no debe tomarte mucho tiempo. Ten cuidado con este tema para que puedas usar todos los formatos, y no pases por alto el formato octal.

Tamao de los tipos primitivos enteros


Cuando este objetivo pide el rango de los tipos de datos primitivos asumo que para representarlo slo se requiere el nmero 2 elevado a la potencia apropiada en lugar del nmero que representa. En mi mente hay slo tres tipos enteros a aprender ya que, en mi experiencia basada en PC. El tamao de un byte es intuitivo: 8 bits.

Rango de los primitivos Enteros Nombre byte short int long Tamao 8 bit 16 bit 32 bit 64 bit Rango -27 to 2 7-1 -215 to 215-1 -231 to 231-1 -2 63 to 2 63-1

Declarando literales enteros


Hay tres maneras de declarar un literal entero. Como esperabas, por defecto, es un valor decimal. Aqu estn las opciones

NT: Algunos documentos utilizan el termino sencillos o bsicos en lugar de primitivos.

95

Tutorial para el examen de certificacin: SCJP 1.2


Declarando 18 como un literal entero Decimal Octal Hexadecimal 18 022 (Cero no la letra O) 0x12

Si compilas y ejecutas esta pequea clase obtendrs en cada ocasin el valor 18.
public class Lit{ public static void main(String[] argv){ int i = 18; int j = 022;//Version Octal: dos veces ocho mas dos int k = 0x12;//Version Hex: una vez diecisis mas dos System.out.println(i); System.out.println(j); System.out.println(k); } }

Roberts y Heller describen 6 maneras de declarar literales enteros, ya que para Java la letra X para la declaracin de un hexadecimal extraordinariamente no es sensible a maysculas, observa que no se utilizan las letras de la A a la F para la notacin hexadecimal. A m me es mas ms fcil recordar nicamente las tres maneras descritas anteriormente y que las letras no son sensibles a maysculas.

Tamao de los tipos primitivos de coma flotante


Los nmeros de coma flotante son especimenes ligeramente extraos debido a que sus clculos pueden tener algunos resultados inesperados. Citando a Peter Van Linden "La precisin exacta depende del nmero que se representa". Como compensacin a esta precisin variable logras conseguir casi jugar con nmeros grandes ms all los que puedas imaginar. As una variable de tipo double puede almacenar un nmero como 17 seguido por 307 ceros. Un numero que sirve incluso para que puedas almacenar los estados financieros de Bill Gates. (hasta que Linux alcance la dominacin mundial total, entonces un entero podr hacer muy bien ese trabajo).

Rango de los tipo de coma flotante float double 32 bit 64 bit

96

javaHispano. Tu comunidad, tu lenguaje. Ten presente que el tipo de dato predefinido para un literal con un componente decimal es un double y no un long. Esto es ligeramente confuso puesto que podras pensar que el tipo predefinido para un nmero de coma flotante debera ser un float. Puedes encontrar preguntas en el examen similares a la siguiente:
Se compilar el siguiente cdigo? float i = 1.0;

Tu intuicin debera decirte que esto debe compilarse sin problemas. Desgraciadamente el examen no esta diseado para probar su intuicin. Esto causar un error en tiempo de compilacin ya que estas intentando asignar un double a un float. Puedes arreglar este cdigo de la manera siguiente:
float i = 1.0F;

o incluso:
float i = (float) 1.0;

Indicando tipos de datos con un literal sufijo


Como se mostr anteriormente puedes indicarle a Java que un literal numrico es de un tipo de dato en particular asignndole un literal sufijo. Estos son los sufijos disponibles: Sufijos para tipos de datos float long double F L D

Los tipos boolean y char


Los tipos de datos primitivos boolean y char son un poco curiosos. Si tienes experiencia programando con C/C++ presta atencin particularmente al tipo boolean y a asegrate de no traer contigo "falsos friends" de cualquiera de estos lenguajes. A un tipo boolean no se le puede asignarse otro valor distinto de true o false. Los valores true o false no corresponden al 0, al -1 o a algn otro nmero.

97

Tutorial para el examen de certificacin: SCJP 1.2

Un dato de tipo boolean nicamente puede recibir los valores de true o false, y no se le puede asignar un nmero como 1 o 0.

El tipo de dato primitivo char es el nico tipo de dato primitivo sin signo. El tipo char se usa para denotar un carcter Unicode. Unicode es un cdigo alternativo al ASCII que almacena caracteres en 2 bytes en lugar de 1 byte como lo hace el cdigo ASCII. Esto te permite representar 65K caracteres, qu aunque no es una cantidad suficientemente grande para cubrir todas las escrituras del mundo, es mejor que los 255 caracteres que nos proporciona el cdigo ASCII. La internacionalizacin es un tema completo por si mismo, y el hecho de que puedas representar caracteres en chino o Vietnams, no significa que se desplegarn correctamente si tienes un sistema operativo en ingls normal. Un literal de tipo char se crea encerrando el carcter con comillas simples:
char a = 'z';

Nota que son comillas simples y no comillas dobles . Todo esto es funcional en mi pequeo mundo basado en el Ingles pero como Java es un sistema mundial un char puede contener cualquiera de los caracteres disponible en el sistema Unicode. Esto se hace usando cuatro dgitos hexadecimales precedidos por \u, con la expresin completa encerrada con comillas simples. As, el espacio en blanco se representa de la siguiente manera:
char c = \u0020;

Si asignas un nmero sencillo a un char, ste ser tomado como un carcter alfabtico. As que el siguiente cdigo mostrar la letra A(valor 65 del cdigo ASCII) seguido de una espacio en blanco.
public class MyChar{ public static void main(String argv[]){ char i = 65; char c = '\u0020'; System.out.println(i); System.out.println("This"+c+"Is a space"); } }

98

javaHispano. Tu comunidad, tu lenguaje.

Declarando literales String


El tipo String no es un tipo de dato primitivo pero es tan importante que en ciertas reas Java lo trata como si lo fuera. Uno de estos rasgos es la habilidad de declarar literales String en lugar de usar new para instanciar una copia de la clase. Las literales String son bastante sinceras. Asegrate de recordar que las literales String son encerradas con comillas dobles mientras que un literal char utiliza comillas simples. As:
String name = "James Bond"

Pregunta 1) Cules de las siguientes lneas se compilarn correctamente? 1) float f=10f; 2) float f=10.1; 3) float f=10.1f; 4) byte b=10b;

Pregunta 2) Cules de las siguientes lneas se compilarn correctamente? 1) short myshort=99S; 2) String name='Excellent tutorial Mr Green'; 3) char c=17c; 4) int z=015;

Pregunta 3) 99

Tutorial para el examen de certificacin: SCJP 1.2

Cules de las siguientes lneas se compilarn correctamente? 1) boolean b=-1; 2) boolean b2=false; 3)int i=019; 4) char c=99;

Respuestas Respuesta 1) 1) float f=10f; 3) float f=10.1f; Para la opcin 4; No existe una literal b(byte), y la opcin 2 causar un error al compilarse debido a que el tipo de dato por omisin para un nmero con un componente decimal es double. Respuesta 2) 4)int z=015; Las letras c y s no existen como indicadores literales y un String debe estar encerrado por comillas dobles y no por comillas simples como en el ejemplo. Respuesta 3) 2) boolean b2=false; 4) char c=99; Te debe ser bastante obvio que la opcin 1 es errnea, a un boolean nicamente se le pueden asignar los valores true y false. La opcin 3 es ligeramente ms difcil de detectar como errnea; ya que, esa es la manera correcta de declarar un literal octal; pero no puedes usar el nmero 9 si estas en base 8 donde tienes nmeros del 0 al 7. Quiz sean un poco tramposas estas ultimas opciones.
Otras Fuentes para este tema: Este tema es cubierto en el Tutorial de SUN en: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/vars.html (No encontraras mencin alguna sobre las literales.)

100

javaHispano. Tu comunidad, tu lenguaje.


Richard Baldwin cubre este tema en: http://www.Geocities.com/Athens/Acropolis/3797/Java020.htm#primitive types (nuevamente no encontraras mencin alguna sobre las literales.) Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec4.html#obj13 Bruce Eckel's Thinking in Java Captulo 2 "Caso Especial: Tipos primitivos Captulo 3 "Literales"

101

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 5. Operadores y Asignaciones


Objetivo 1
Determinar el resultado de aplicar cualquier operador, incluyendo los operadores de asignacin y el operador instanceof, sobre operandos de cualquier tipo de clase, dependiendo de su alcance, accesibilidad, o de la combinacin de estos.

El operador instanceof
El operador instanceof es una bestia extraa, desde mi punto de vista debera ser un mtodo en lugar de un operador. Probablemente has escrito bastante cdigo con Java y no has tenido la necesidad de usarlo, pero para propsitos del examen necesitas conocerlo. Este operador retorna un valor booleano como resultado a una prueba sobre un tipo de clase en tiempo de ejecucin. Y efectivamente, como estas pensando, se usa para preguntar: Es esta_clase instanciade esta_otra_clase? Si lo utilizas en casos triviales como el siguiente, quiz no le veas mucha utilidad:
public class InOf { public static void main(String argv[]){ InOf i = new InOf(); if(i instanceof InOf){ System.out.println("It's an instance of InOf"); }//End if }//End of main }

Como habrs deducido el resultado ser: It's an instance of InOf

Sin embargo, pueden surgir situaciones donde nicamente tienes acceso a una referencia de un objeto, el cual se refiere a algo que esta ms arriba o ms abajo en la jerarqua de clases del programa. As puedes tener un mtodo que tome como parmetro un componente que puede referirse a un botn, a una etiqueta o a cualquier otra cosa. En estas circunstancias, el operador instanceof se usa para examinar el tipo del objeto, realizar una comparacin y una conversin y as llamar al mtodo ms apropiado. El siguiente cdigo ilustra un ejemplo de esto:
import java.awt.*;

102

javaHispano. Tu comunidad, tu lenguaje.

public class InOfComp { public static void main(String argv[]){ }//End of main public void mymethod(Component c){ if( c instanceof Button){ Button bc = (Button) c; bc.setLabel("Hello"); }else if (c instanceof Label){ Label lc = (Label) c; lc.setText("Hello"); } }//End of mymethod }

Si en tiempo de compilacin la examinacion del tipo de la clase y la conversin forzada no fueran realizadas, los mtodos setLabel y setText no estaran disponibles. Observa que el operador instanceof se aplica a los nombres de las clases no a una referencia de un objeto para una clase.

El operador +
Como esperabas, el operador + adiciona 2 nmeros entre si. As la siguiente lnea de cdigo mostrar 10:
int p=5; int q=5; System.out.println(p+q);

El operador + es un ejemplo raro de la sobrecarga de operadores en Java. los programadores en C++ estn acostumbrados a poder sobrecargar operadores para que estos signifiquen cualquier cosa que ellos definan. Esta facilidad no est disponible para un programador en Java, sin embargo esta opcin esta disponible para los Strings, ya que el signo mas(+) se sobrescribe para ofrecer la concatenacin de Strings. De esta manera el siguiente cdigo s se compilar:
String s = "One"; String s2 = "Two" String s3 = ""; s3 = s+s2; System.out.println(s3);

103

Tutorial para el examen de certificacin: SCJP 1.2 El resultado ser "OneTwo", observa que no hay espacios entre las dos cadenas unidas. Bajo ciertas circunstancias Java realiza una llamada implcita el mtodo toString. Este mtodo, como su nombre lo dice, intenta convertir a un String a el objeto que lo llama. Para un entero con valor 10, la llamada a toString retornara la cadena "10". Lo anterior se aprecia mejor en el siguiente cdigo
int p = 10; String s = "Two"; String s2 = ""; s2 = s + p; System.out.printlns(s2); el resultado ser: Two10

Recuerda que para los Strings, nicamente el operador + esta sobrecargado. Si intentas utilizar sobre un String los operadores divisin y menos(/,-) causaras un error.

Asignando variables primitivas de tipos diferentes


Un booleano nica y exclusivamente puede recibir otro valor de tipo booleano. Para los programadores C/C++, recuerden que esto significa que a un booleano no se le puede asignar -1 o 0, ya que en Java un booleano no es substituible por el numero cero o un valor distinto de cero. Con esta principal excepcin en el tipo de datos boolean, el principio general para entender este objetivo esta en saber que las conversiones por "ensanchamiento" estn permitidas en Java, siempre y cuando no impliquen exactitud. Por ensanchamiento quiero decir que una variable como un byte que ocupa 1 byte (ocho bits) puede asignarse a una variable que ocupa ms bits como por ejemplo un int. Sin embargo si intentas asignar un int a un byte conseguirs un error en tiempo de compilacin:
byte b= 10; int i = 0; b = i;

104

javaHispano. Tu comunidad, tu lenguaje.

Los datos primitivos pueden ser asignados a tipos de datos mas "anchos", un booleano nicamente puede ser asignado a otro booleano.

Como esperabas, no puedes asignar datos primitivos a objetos y viceversa. As, el siguiente cdigo no es valido:
int j=0; Integer k = new Integer(99); j=k; //Asignacion ilegal de un objeto un tipo primitivo.

Una diferencia importante entre la asignacin de objetos y la asignacin de tipos primitivos, es que los tipos primitivos son revisados en tiempo de compilacin mientras que los objetos son revisados en tiempo de ejecucin. Esto se cubrir mas adelante ya que tiene implicaciones importantes cuando un objeto no esta completamente resuelto en tiempo de compilacin. Por supuesto, puedes realizar una conversin forzada para hacer que una variable se ajuste a un tipo de datos mas estrecho, Esto a menudo no es aconsejable ya que el resultado perder precisin, pero es valido si realmente lo quieres hacer. Java utiliza la convencin de C/C++ encerrando entre parntesis () el tipo de datos al que se quiere convertir. Por lo tanto el siguiente cdigo se compilara y ejecutara sin problemas:
public class Mc{ public static void main(String argv[]){ byte b=0; int i = 5000; b = (byte) i; System.out.println(b); } }

el resultado es
-120

Posiblemente no es un valor que te sea muy til.

Asignando referencias de objetos de diferentes tipos.


Cuando asignamos referencias de objetos, otra regla general es que puedes realizar la asignacin de abajo hacia arriba en la jerarqua de clases, pero no de arriba hacia abajo. Puedes ver esto de la siguiente manera. Si tu asignas una instancia de una clase hija a la

105

Tutorial para el examen de certificacin: SCJP 1.2 clase Base, Java sabr qu mtodos estn en la clase hija. Sin embargo una clase hija puede tener mtodos adicionales de los que le proporciona la clase Base. Puedes solucionar este problema usando la conversin forzada.
Las referencias de objetos se asignan hacia arriba en la jerarqua de clases.

El siguiente ejemplo muestra que ocurre cuando fuerzas la asignacin de una referencia de un objeto hacia una clase de jerarqua superior:
class Base{} public class ObRef extends Base{ public static void main(String argv[]){ ObRef o = new ObRef(); Base b = new Base(); b=o;//Esta linea se compilara sin error /*o=b; Esto debe causar un error indicando que se requiere una conversion forzada para asignar una referencia de Base a ObRef */ } }

Operadores de desplazamiento de bits.


Odio un poco esto de trabajar con desplazamientos de bits. Ya que implica que llenes tu mente con una capacidad no intuitiva que es trabajar con nmeros infinitamente pequeos, nmeros que un programador quiz nunca utilizara. Pero debido a que todas las razones para aprenderlo son por que pueden aparecer en el examen, es mejor tratar el tema, pues es poco probable que lo aprendas de otra manera. El resultado de usar estos operadores puede sorprenderte. Para entenderlos tienes que tener un pensamiento binario bastante fluido, por ejemplo conocer el valor de un bit en cada posicin:
32, 16, 8, 4, 2, 1

Los programadores C/C++, pueden estar tranquilos ya que la manera de trabajar del operador de desplazamiento de bits en Java es menos ambigua que en C/C++. En C/C++ el desplazamiento hacia la derecha puede ser con signo o sin signo dependiendo de la implementacin del compilador. Si vienes de programar con Visual Basic, bienvenido a la programacin de bajo nivel. 106

javaHispano. Tu comunidad, tu lenguaje.

Observa que el objetivo nicamente pide que comprendas el resultado de aplicar estos operadores sobre valores de tipo int. Esto es tambin aplicable a un byte o a un short, particularmente si el valor es negativo, ya que se puede tener algunos resultados demasiado inesperados.

Operadores de desplazamiento con signo << y >>


Los operadores de desplazamiento a la derecha y a la izquierda mueven el patrn de bits hacia la derecha o hacia la izquierda y dejan solo al bit de signo del nmero. Para nmeros positivos los resultados son bastante predecibles. As el desplazamiento con signo para nmeros positivos da los siguientes resultados:
int x = 14; int y = 0; y = x >>2; System.out.println(y);

El resultado ser 3,se pierde un bit y el resto del patrn de bits se inclina a la derecha
int x = 14; int y = 0; y = x <<2; System.out.println(y);

El resultado ser 56 De manera que, Qu esperaras obtener al realizar un desplazamiento a la izquierda a un numero negativo? Podras esperar el mismo resultado obtenido al desplazar a la derecha un nmero positivo excepto que el resultado mantiene el signo negativo. Si desplazamos 4 posiciones, lo que sucede es que cada una de las posiciones, debido al moviendo de los otros bits, toman el valor del bit ms significativo (el bit de signo). El efecto de esto es que cada desplazamiento divide/multiplica el nmero negativo por dos. Esto te ser fcil de entender hasta que te des cuenta de las implicaciones del almacenamiento de nmeros binarios a travs del complemento a dos. El complemento a dos funciona un poco como el odmetro fsico que se encuentra en el tablero de los coches. Imagina que lo "rebobinas" hasta cero y despus pasas a nmeros negativos. El primer nmero que obtendras no sera 1, sera uno por debajo del mximo que pudieras representar con las ruedecillas disponibles. Si esto te suena improbable ejecuta la calculadora de Windows, ponla en modo cientfico, introduce un nmero negativo y despus pasa a modo binario. Esto te mostrar el patrn de bits del nmero que hayas introducido.

107

Tutorial para el examen de certificacin: SCJP 1.2 Si toda esta charla sobre patrones de bits y representacin en complemento a dos "hace que tu cabeza heche humo", podras preferir pensar el desplazamiento de bits como un proceso repetitivo de multiplicacin o divisin por dos. Esta aproximacin funciona bien hasta que empiezas a desplazar un numero negativo a la derecha, de modo que pierde bits del lado derecho.

Desplazamiento sin signo a la derecha >>>


El desplazamiento sin signo a la derecha >>> realiza un desplazamiento sin tomar en cuenta el bit del signo. As, en un int, los 32 bits son desplazados el numero de veces que se le indique al operador y son rellenados los espacios de la izquierda con ceros. De tal manera que esto da el efecto de convertir un nmero negativo a positivo Este desplazamiento puede darnos algunos resultados muy raros. Veamos la siguiente sentencia:
System.out.println(-1 >>>1); El resultado es el siguiente: 2147483647

El examen probablemente no te pedir que des el resultado exacto pero podra darle algunas alternativas como 0, -1, etc. y tendrs que elegir el resultado mas aproximado. Cual crees que sea el resultado para la siguiente lnea de cdigo?
System.out.println(-1 >>> 32);

Si acabas de leer que el deslazamiento sin signo no toma en cuenta el bit del signo, el resultado de la lnea anterior, que es -1, puede ser una sorpresa. La razn es que el modulo 32 se realiza sobre el operando antes del desplazamiento. As, si divides 32 entre 32 obtienes 0 y si realizas un desplazamiento sin signo de cero lugares hacia la derecha tendrs todava como valor -1. No deseches esto como si fuera una peculiaridad irrelevante ya que puede venir en el examen. He creado un applet que te permite probar varias operaciones de desplazamiento y ver los resultados tanto en decimal como el patrn de bits. Tambin se incluye el cdigo para que veas como trabaja, puedes revisarlo en:
http://www.jchq.net/applets/BitShift/BitShiftAr.html Aqu hay una imagen que muestra el applet en funcionamiento.

Applet BitShift

108

javaHispano. Tu comunidad, tu lenguaje.

Pregunta 1)
Dadas las siguientes clases: interface IFace{} class CFace implements IFace{} class Base{} public class ObRef extends Base{ public static void main(String argv[]){ ObRef ob = new ObRef(); Base b = new Base(); Object o1 = new Object(); IFace o2 = new CFace(); } } Cuales de las siguientes lneas son vlidas? 1) o1=o2; 2) b=ob;

109

Tutorial para el examen de certificacin: SCJP 1.2


3) ob=b; 4) o1=b;

Pregunta 2) Dadas las siguientes declaraciones: String s = "Hello"; long l = 99; double d = 1.11; int i = 1; int j = 0; Cuales de las siguientes lneas compilaran sin error? 1) j=i <<s; 2) j=i<<j; 3) j=i<<d; 4) j=i<<l;

Pregunta 3) Dadas las siguientes variables: char c = 'c'; int i = 10; double d = 10; long l = 1; String s = "Hello"; Cuales de las siguientes lneas compilaran sin error? 1) c=c+i; 2) s+=i; 3) i+=s; 4) c+=s;

Pregunta 4) Cual ser el resultado de la siguiente sentencia? System.out.println(-1 >>>1); 1) 0 2) -1 3) 1

110

javaHispano. Tu comunidad, tu lenguaje.


4) 2147483647

Pregunta 5) Cual ser el resultado de la siguiente sentencia? System.out.println(1 <<32); 1) 1 2) -1 3) 32 4)-2147483648

Pregunta 6) Cuales de las siguientes sentencias son validas? 1) 2) 3) 4) System.out.println(1+1); int i= 2+'2'; String s= "on"+'one'; byte b=255;

Respuestas Respuesta 1) 1)o1=o2; 2)b=ob; 4)o1=b; Respuesta 2) 2)j= i<<j; 4)j=i<<l; Respuesta 3) 2)s+=i; Respuesta 4) 4) 2147483647

An y cuando no logres grabarte este numero, nicamente entendiendo al desplazamiento sin signo a la derecha te puedes dar cuenta que todas las otras opciones no son correctas.
Respuesta 5)

111

Tutorial para el examen de certificacin: SCJP 1.2


1) 1

Con el desplazamiento a la izquierda, los bits son "envueltos alrededor" del patrn de bits. As, el resultado de:
System.out.println(1 <<31); Ser: -2147483648 Respuesta 6) 1) System.out.println(1+1); 2) int i= 2+'2';

La opcin 3 no es valida, ya que las comillas simples sirven para indicar un solo caracter constante y no a una cadena. La opcin 4 no compilara ya que el valor 255 esta fuera del rango de un byte.

Otras Fuentes para este tema: El tutorial de Sun http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html No encontr nada relacionado con el operador instanceof Richard Baldwin http://home.att.net/~baldwin.dick/Intro/Java022.htm#bitwiseoperations No encontr nada relacionado con el operador instanceof Jyothi Krishnan cubre este tema en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec5.html#obj15

112

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2.
Determinar el resultado de aplicar el mtodo booleano equals(Object) sobre Objetos, y cualquier combinacin de las clases java.lang.String, java.lang.Boolean y java.lang.Object.

Diferencia entre el mtodo equals y el operador = =


El mtodo equals puede verse como la realizacin de una comparacin profunda del valor de un objeto, por el contrario el operador = = realiza una comparacin poco profunda. El mtodo equals compara lo que un objeto apunta en lugar del apuntador en si (esto si consideramos que java tiene punteros ).

Usando el mtodo equals con Strings


El mtodo equals retorna un valor primitivo de tipo boolean. Esto significa que se puede usar para manejar sentencias if, while u otra sentencia de enciclamiento. Puede usarse tambin en lugar del operador = = con una primitiva. La utilizacin del mtodo equals y el operador = = tiene extraos efectos laterales cuando se usa para comparar Strings. Esta es una de las ocasiones en donde la naturaleza inmutable de los Strings, y la manera en que java maneja esta caracterstica, puede crearte confusin. Existen 2 maneras para crear un String en Java. Una de ellas implica la utilizacin del operador new. As, normalmente un String se crea de la siguiente manera:
String s = new String("Hello");

La otra manera, ligeramente ms corta, es la siguiente:


String s = "GoodBye";

Generalmente la diferencia entre estas dos maneras de crear un String es mnima, pero en el examen pueden haber preguntas que te exijan reconocer muy bien esta diferencia. La creacin de 2 cadenas con la misma secuencia de letras sin ocupar la palabra clave new creara 2 apuntadores a la misma cadena en el pool de Strings de Java. El pool de Strings es la manera en que Java mantiene los recursos. Veamos lo siguiente para comprender mejor lo anterior:
String s = "Hello"; String s2 = "Hello"; if (s = = s2){

113

Tutorial para el examen de certificacin: SCJP 1.2


System.out.println("Equal without new operator"); } String t = new String("Hello"); String u = new String("Hello"); if (t == u){ System.out.println("Equal with new operator"); }

Tomando en cuenta lo que vimos en el objetivo anterior, esperaras que el primer mensaje "Equal without new operator", nunca se mostrara ya que s y s2 son objetos distintos, y adems el operador = = examina lo que apunta a un objeto, no su valor. Sin embargo, debido a la manera en que Java maneja los recursos con la re-utilizacin de cadenas idnticas que son creadas sin el operador new, s y s2 tiene la misma "direccion" y en consecuencia el cdigo mostrar el mensaje:
"Equal without new operator"

Por otro lado, en el segundo par de Strings t y u, el operador new fuerza a Java a crear cadenas separadas, es decir, dos objetos distintos. Y debido a que el operador = = nicamente compara la direccin del objeto, y no su valor, t y u tienen diferentes direcciones y as el mensaje "Equal with new operator" nunca se mostrar.

El mtodo equals aplicado a Strings, sin importar la manera en que fueron creadas, ejecuta una comparacin caracter a caracter.

La manera en que trabaja el pool de String y la diferencia entre usar el operador = = y el mtodo equals no es muy obvio, particularmente si tienes antecedentes de programar con Visual Basic. La mejor manera de comprender esto es creando algunos ejemplos por ti mismo y viendo como es que trabajan. Prueba permutando cadenas idnticas creadas con y sin el operador new.

Usando el mtodo equals con la Clase Boolean


El para comprender el uso del operador equals sobre java.lang.Boolean es una confusin potencial. Boolean es un objeto envolvente para la primitiva boolean De acuerdo a la documentacin del JDK el mtodo equals en la clase Boolean: "Retorna true si y solo si el argumento que recibe es distinto de null y si el objeto Boolean que recibe tiene el mismo valor booleano que ste objeto" 114 requerimiento

javaHispano. Tu comunidad, tu lenguaje.

Ejemplo:
Boolean b1 = new Boolean(true); Boolean b2 = new Boolean(true); if(b1.equals(b2)){ System.out.println("We are equal"); }

Como un tema aparte sobre el uso de boolean y Boolean, una vez que te familiarices con la sentencia if en Java te dars cuenta que no puedes realizar la conversin implcita tan apreciada por los programadores C/C++. Esa conversin es del tipo:
int x =1; if(x){ //realiza }

algo, pero no en Java

Esto no funcionara en Java porque el parmetro para la sentencia if debe ser una evaluacin booleana, ya que Java no tiene el concepto de C/C++ en donde cualquier valor no nulo se considera verdadero. Sin embargo puedes realizar lo siguiente en Java :
boolean b1=true; if(b1){ //do something in java }

Aunque esta es una practica de programacin bastante mala es sintcticamente correcta, ya que el parmetro para la sentencia if es un booleano.

Usando el mtodo equals con objetos


Debido al diseo fundamental de Java una instancia de cualquier clase es tambin una instancia de la clase java.lang.Object. Examinaremos esto utilizando el mtodo toString. Para la clase Object, el mtodo toString simplemente retorna la direccin de memoria. As el resultado es el equivalente de ejecutar una comparacin con el operador = =. Como Java no esta diseado para manipular direcciones de memoria o apuntadores, sta no es una operacin particularmente til. Veamos el siguiente ejemplo:
public class MyParm{ public static void main(String argv[]){ Object m1 = new Object(); Object m2 = new Object(); System.out.println(m1);

115

Tutorial para el examen de certificacin: SCJP 1.2


System.out.println(m2); if (m1.equals(m2)){ System.out.println("Equals"); }else{ System.out.println("Not Equals"); } } }

Si intentas compilar y ejecutar lo anterior, obtendrs algo similar a lo siguiente:


java.lang.Object@16c80b java.lang.Object@16c80a Not Equals

Estos valores son direcciones de memoria , y probablemente no tienen nada que ver con lo que tu necesitas.

Pregunta 1) Que pasar cuando intentes compilar y ejecutar el siguiente cdigo?


public class MyParm{ public static void main(String argv[]){ String s1= "One"; String s2 = "One"; if(s1.equals(s2)){ System.out.println("String equals"); } boolean b1 = true; boolean b2 = true; if(b1.equals(b2)){ System.out.println("true"); } } }

116

javaHispano. Tu comunidad, tu lenguaje.

1)Error al compilar 2)No se mostrar ningn mensaje 3)Se mostrar nicamente el mensaje "String equals" 4)Se mostrar el mensaje "String equals", seguido de "true"

Pregunta 2) Que pasar cuando intentes compilar y ejecutar el siguiente cdigo?


String s1= "One"; String s2 = new String("One"); if(s1.equals(s2)){ System.out.println("String equals"); } Boolean b1 = new Boolean(true); Boolean b2 = new Boolean(true); if(b1==b2){ System.out.println("Boolean Equals"); }

1)Error al compilar 2)Se mostrar nicamente "String equals" 3)Se mostrar "String equals" seguido de "Boolean Equals" 4)Se mostrar nicamente "Boolean Equals"

Pregunta 3) Cul es el resultado de intentar compilar y ejecutar el siguiente cdigo?


Object o1 = new Object(); Object o2 = new Object(); o1=o2; if(o1.equals(o2)) System.out.println("Equals"); }

1)Error al compilar 2)Mostrar "Equals" 3)No mostrar nada 4)Error al ejecutarse

117

Tutorial para el examen de certificacin: SCJP 1.2 Respuestas Respuesta 1) 1)Error al compilar la lnea b1.equals causar un error debido a que b1 es un valor primitivo y los valores primitivos no tienen mtodos. Si b1 hubiera sido creado son la clase Boolean entonces si podras ocupar el mtodo equals. Respuesta 2) 2)Se mostrar nicamente "String equals" Probar una instancia de la clase Boolean con el operador = = nicamente examina la direccin de memoria, no el valor de la instancia. Respuesta 3) 2)Mostrar "Equals" Debido a que una instancia de Object a sido asignada a la otra en la lnea: o1=o2 Estas instancias apuntan ahora a la misma direccin de memoria y en consecuencia, la aplicacin del mtodo equals retornar verdadero. Otras Fuentes para este tema Jyothi Krishnan cubre este tema en http://www.geocities.com/SiliconValley/Network/3693/obj_sec5.html#obj16 Michael Thomas http://www.michael-thomas.com/java/JCP_Operators.htm#equals()

118

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 3.
En una expresin que involucre a los operadores &,|,&&,||, y variables, conocer el estado de los valores que son evaluados con estos operadores y el valor de la expresin. Es fcil olvidarse cuales son los smbolos que significan una operacin lgica y cuales significan operaciones a nivel de bits, asegrate de reconocer la diferencia para el examen. Si eres nuevo con el uso de estos operadores vale la pena que te asegures no confundirte con los operadores a nivel de bits y los operadores lgicos.

El efecto corto circuito con los operadores lgicos.


Los operadores lgicos (&&, ||) tienen un ligero efecto peculiar en una operacin lgica llamado "corto circuito, como ocurre de manera similar, en C/C++. Esto quiz te pueda sorprender si vienes de programar con Visual Basic ya que Visual Basic evala todos los operandos. En Java esto tiene sentido si consideras que en una operacin AND, si el primer operando es falso ya no es necesario evaluar el segundo operando, el resultado final ser, con certeza, falso. Lo mismo ocurre con el operador lgico OR, si el primer operando ha resultado verdadero, el clculo global ser verdadero ya que slo un operando del OR debe retorna verdadero para que el resultado final sea verdadero. Esto puede traer cdigo un efecto especial con esos clculos reducidos que dependen de efectos laterales. Veamos el siguiente ejemplo:
public class MyClass1{ public static void main(String argv[]){ int Output=10; boolean b1 = false; if((b1==true) && ((Output+=10)==20)) { System.out.println("We are equal "+Output); }else { System.out.println("Not equal! "+Output); } } }

El resultado de este cdigo ser "Not equal 10". Esto muestra que la operacin Ouput+=10 jams ser realizada debido a que el proceso se detiene despus de que se evala la primera operacin, debido a que retorna falso, y al estar aplicando el operador

119

Tutorial para el examen de certificacin: SCJP 1.2 AND (&&) ya no es necesario evaluar el resto de la expresin, pues el resultado ser falso. Si cambias el valor de b1 a verdadero, la operacin se realizar y el resultado ser el que esperabas: "We are equal 20". Esto a veces puede ser conveniente cuando realmente no quieras procesar otras operaciones si una de ellas retorna falso, pero puede tener un efecto lateral inesperado si no ests completamente familiarizado con el uso de estos operadores.

Operadores a nivel de bits.


Los operadores | y & se aplican para realizar operaciones AND y OR a nivel de bits. Puedes encontrarte preguntas en el examen que te den nmeros en decimal y te pidan que realices operaciones AND o OR a nivel de bits. Para hacer esto, necesitas familiarizarte con la conversin de nmeros decimales a binarios y conocer que ocurre con el patrn de bits. Este es un ejemplo tpico Cul es el resultado de la siguiente operacin?
3|4

El patrn binario para el decimal 3 es 11, el patrn binario para 4 es 100, para realizar una operacin OR a nivel de bits, cada bit es comparado con el bit que se encuentra en la misma posicin del otro nmero. Si alguno de los bits es 1 el bit del numero resultante, en la posicin que se esta comparando, es tambin 1. As para esta operacin el resultado ser: 011 100 -----111 y 111 es 7 en decimal. Los objetivos no especifican que conozcas la operacin XOR a nivel de bits. realizada con el operador .

Pensando en binario
Si no te siente muy cmodo pensando en binario (yo me siento mucho mas cmodo pensando en decimal), puedes querer hacer algunos ejercicios para ayudarte a dominar este tema y tambin el relacionado con los operadores de desplazamiento de bits. Si ests

120

javaHispano. Tu comunidad, tu lenguaje. ejecutando Windows puedes encontrar til usar la calculadora que proporciona este sistema operativo en modo cientfico. Para hacer esto solo elige la opcin Ver y cambiar del modo Estndar predefinido al modo cientfico. En modo cientfico puedes cambiar entre ver los nmeros en formato decimal y binario, esto despliega el patrn de bits de los nmeros. Y si lo prefieres puedes realizar un programa que muestre el patrn de bits de un numero, utilizando la clase Integer, he aqu un pequeo programa que muestra un ejemplo:
public class BinDec{ public static void main(String argv[]){ System.out.println(Integer.parseInt("100",2)); System.out.println(Integer.toString(64,2)); } }

Si lo compilas y ejecutas este ser el resultado:


4 1000000

Observa que el programa convierte el patrn de bits 100 en su equivalente en decimal, que es 4; y convierte el decimal 64 en su patrn de bits equivalente.

Pregunta 1) Que pasar cuando intentes compilar y ejecutar el siguiente cdigo?


int Output=10; boolean b1 = false; if((b1= =true) && ((Output+=10)==20)){ System.out.println("We are equal "+Output); }else{ System.out.println("Not equal! "+Output); }

1)Error al compilar, por intentar realizar una comparacin binaria sobre tipos de datos lgicos 2)Se compilara y mostrar la cadena "We are equal 10" 121

Tutorial para el examen de certificacin: SCJP 1.2 3)Se compilara y mostrar la cadena "Not equal! 20" 4)Se compilara y mostrar la cadena "Not equal! 10"

Pregunta 2) Qu mostrar la siguiente lnea de cdigo


System.out.println(010|4);

1) 14 2) 0 3) 6 4) 12

Pregunta 3) Cuales de los siguientes fragmentos de cdigo se compilara sin errores 1)


int i=10; int j = 4; System.out.println(i||j); 2) int i=10; int j = 4; System.out.println(i|j);

3)
boolean b1=true; boolean b2=true; System.out.println(b1|b2);

4)
boolean b1=true; boolean b2=true; System.out.println(b1||b2);

Respuestas)
Respuesta 1

4)Se compilara y mostrar la cadena "Not equal! 10" Respuesta 2) 122

javaHispano. Tu comunidad, tu lenguaje.

4)12 La respuesta a esta pregunta requiere que conozcas la notacin octal, el cero que antecede al primer numero indica que dicho nmero esta en notacin octal, 010 es la notacin octal para el numero 8 decimal.
As, la instruccin: System.out.println(010|4)

es equivalente a:
System.out.println(8|4);

que en binario es: 1000 0100 ----1100 y 1100 en decimal es 12 Repuesta 3) 2,3,4 La opcin 1 no compilara ya que estas intentando ejecutar una aplicacin OR lgica sobre tipos enteros. Y una operacin lgica solo se puede realizar con argumentos de tipo boolean. Otras Fuentes para este tema Tutorial de Sun: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html Richard Baldwin http://home.att.net/~baldwin.dick/Intro/Java022f.htm

123

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 4
Determinar los efectos sobre los objetos y los valores primitivos al pasarlos como variables en mtodos al aplicarles asignaciones u otras modificaciones dentro del mtodo.

Nota sobre este objetivo


El objetivo parece estarte pidiendo que entiendas lo que ocurre cuando pasas un valor a un mtodo. Si el cdigo dentro del mtodo modifica el valor de la variable, El cambio es visible aun fuera del mtodo? Si vienes de programar con C/C++ estars familiarizado con el concepto "paso de parmetros por valor" y "paso de parmetros por referencia" con el operador &. En java no hay tal opcin ya que todo es pasado por valor. Sin embargo esto no siempre es as. Si pasas un objeto este es una referencia a un objeto y no puedes manipular directamente una referencia a un objeto. As, si manipulas un campo de un objeto que se pasa a un mtodo, el campo se comportara como si lo hubieras pasado por referencia (esto quiere decir que cualquier cambio mantendr su efecto an despus de terminada la llamada al mtodo).

Referencias de Objetos como parmetros de mtodos.


Veamos el siguiente ejemplo:
class ValHold{ public int i = 10; } public class ObParm{ public static void main(String argv[]){ ObParm o = new ObParm(); o.amethod(); } public void amethod(){ ValHold v = new ValHold(); v.i=10; System.out.println("Before another = "+ v.i); another(v); System.out.println("After another = "+ v.i); }//End of amethod public void another(ValHold v){ v.i = 20; System.out.println("In another = "+ v.i); }//End of another

124

javaHispano. Tu comunidad, tu lenguaje.


} El resultado ser: Before another = 10 In another = 20 After another = 20

Observa como el valor de la variable i ha sido modificado. Si java siempre pasa por valor, Cmo se ha modificado? Bueno, el mtodo recibi una copia del manejador o referencia del objeto pero esa referencia acta como un apuntador al valor real del objeto y las modificaciones se reflejan en los campos a los que apunta. Esto es parecido a la desreferenciacin automtica de punteros en C/C++.

Primitivas como parmetros de mtodos


Cuando pasas valores primitivos a mtodos, estos pasan por valor. El mtodo obtiene su propia copia para utilizarla y en consecuencia, cualquier modificacin no se refleja fuera del mtodo. Veamos el siguiente ejemplo:
public class Parm{ public static void main(String argv[]){ Parm p = new Parm(); p.amethod(); }//End of main public void amethod(){ int i=10; System.out.println("Before another i= " +i); another(i); System.out.println("After another i= " + i); }//End of amethod public void another(int i){ i+=10; System.out.println("In another i= " + i); }//End of another }

La salida ser:
Before another i= 10 In another i= 20 After another i= 10

125

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 1) Dado el siguiente cdigo:


class ValHold{ public int i = 10; } public class ObParm{ public static void main(String argv[]){ ObParm o = new ObParm(); o.amethod(); } public void amethod(){ int i = 99; ValHold v = new ValHold(); v.i=30; another(v,i); System.out.println(v.i); }//End of amethod public void another(ValHold v, int i){ i=0; v.i = 20; ValHold vh = new ValHold(); v = vh; System.out.println(v.i+ " "+i); }//End of another }

Cual ser la salida? 1)10,0, 30 2)20,0,30 3)20,99,30 4)10,0,20

Respuestas
Respuesta 1

4)10,0,20

126

javaHispano. Tu comunidad, tu lenguaje. Otras Fuentes para este tema: Tutorial de SUN: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html Jyothi Krishnan cubre este tema en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec5.html#obj18

127

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 6. Sobrecarga, sobreescritura, tipos en tiempo de ejecucin y orientacin a objetos


Objetivo 1)
Mostrar los beneficios de la encapsulacin en el diseo orientado a objetos y escribir cdigo que implemente clases fuertemente encapsuladas y entender las relaciones es un y tiene un.

Relaciones es un y tiene un
ste es un tema bsico de OO y probablemente te encontrars una pregunta sobre l en el examen. Esencialmente busca descubrir si entiendes cundo algo se refiere al tipo de estructura de clases a la que pertenece un objeto y cundo se refiere a un mtodo o campo que posee una clase. As, un gato ES UN tipo de animal y un gato TIENE UNA cola. Desde luego la distincin puede ser difusa. Si fueras un zologo y conocieras los nombres correctos para los grupos de tipos de animales podras decir que un gato ES UN:
Largapalabraenlatnparagrupodeanimalesconcolas

Pero en lo que al examen se refiere esto no es un requisito. Las preguntas del examen tienden a ser del tipo en las que se te da un texto que describe una jerarqua potencial y te hace preguntas como: qu debera ser un campo y qu debera ser un nuevo tipo de clase como hijo. A primera vista estas cuestiones pueden parecer complejas, pero son bastante obvias si las lees con cuidado

Encapsulamiento
Los objetivos de Java 1.1 no mencionaban especficamente la encapsulacin aunque sera raro estudiar Java y no encontrarse con el concepto. La encapsulacin conlleva a separar la interfaz de una clase de su implementacin. Esto significa que no se puede corromper el valor de un campo accidentalmente, hay que usar un mtodo para cambiar un valor.

La encapsulacin conlleva esconder los datos de una clase y permitir el acceso solo mediante una interfaz pblica.

128

javaHispano. Tu comunidad, tu lenguaje. Esto usualmente conlleva la creacin de variables privadas (campos) cuyo valor se actualiza y recupera mediante mtodos. La convencin estndar para dar nombre a estos mtodos es: SetNombreCampo GetNombreCampo
Por ejemplo, si cambiaras el color de una figura podras crear un par de mtodos de la siguiente manera public void setColor(Color c){ cBack = c; } public Color getColor(){ return cBack; }

Las principales palabras claves para controlar el acceso a las variables son: public private protected

No te confundas pensando que el sistema de control de acceso tiene que ver con la seguridad. Este no est diseado para evitar que un programador acceda a variables, est diseado para ayudar a evitar modificaciones no deseadas.

El enfoque estndar al usar el ejemplo de arriba de color sera hacer privado el campo CBack de Color. Un campo privado slo es visible desde la clase en cuestin. Esto significa que un programador no puede accidentalmente escribir cdigo que cambie el valor desde otra clase. Esto puede ayudar a reducir la introduccin de errores. La separacin de la interfaz y la implementacin hace ms fcil modificar el cdigo de una clase sin afectar a otro cdigo que lo pueda usar. Para el diseador de clases esto lleva a la posibilidad de modificar una clase, sabiendo que no estropear programas que la usen. Un diseador de clases puede aadir rutinas de comprobacin adicionales para realizar chequeos de cordura relacionados con modificaciones de campos. He trabajado en proyectos de seguros en los que era posible que el cliente tuviera una edad menor de cero. Si un valor as se guarda en un campo simple como un entero, no hay un lugar obvio en el que se puedan guardar rutinas de comprobacin. Si la edad es accesible slo va mtodos set y get ser posible insertar comprobaciones de edades cero o negativas de forma que no quede afectado cdigo existente. Desde luego a medida que el desarrollo contina se pueden descubrir ms situaciones que necesiten chequeo. Para el usuario final de la clase esto significa que no tiene que comprender el funcionamiento interno y que se le presenta una interfaz claramente definida para manejar los datos. El usuario final puede tener la confianza de que las actualizaciones en el cdigo de la clase no rompern su cdigo existente.

129

Tutorial para el examen de certificacin: SCJP 1.2

Tipos en Tiempo de ejecucin


Como el polimorfismo permite seleccionar en tiempo de ejecucin la versin que se ejecuta de un mtodo, a veces no es obvio cul ser el mtodo ejecutado. Vase el siguiente ejemplo.
class Base { int i=99; public void amethod(){ System.out.println("Base.amethod()"); } } public class RType extends Base{ int i=-1; public static void main(String argv[]){ Base b = new RType();//<= Ntese el tipo System.out.println(b.i); b.amethod(); } public void amethod(){ System.out.println("RType.amethod()"); } }

Ntese cmo el tipo de la referencia es la variable b es la clase Base pero el tipo de la clase de hecho es RType. La llamada a amethod invocar la versin en RType pero la salida b.i referenciar el campo i en la clase Base.

Pregunta 1) Supn que te han entregado el siguiente diseo: Una persona tiene nombre, edad, direccin y sexo. Ests diseando una clase para representar un tipo de persona llamada paciente. Este tipo de persona puede recibir un diagnstico, tener cnyuge y est vivo". Dado que la clase persona ya ha sido creada, qu de entre lo siguiente sera apropiado incluir cuando se disee la clase paciente?

130

javaHispano. Tu comunidad, tu lenguaje.

1)fecha de registro 2)edad 3)sexo 4)diagnstico Pregunta 2) Qu suceder cuando intentes compilar y ejecutar el siguiente cdigo?
class Base { int i=99; public void amethod(){ System.out.println("Base.amethod()"); } Base(){ amethod(); } } public class RType extends Base{ int i=-1; public static void main(String argv[]){ Base b = new RType(); System.out.println(b.i); b.amethod(); } public void amethod(){ System.out.println("RType.amethod()"); } }

1) RType.amethod -1 RType.amethod 2)
RType.amethod 99 RType.amethod

3)
99 RType.amethod

131

Tutorial para el examen de certificacin: SCJP 1.2 4)


Error en tiempo de compilacin

Pregunta 3) Tu jefe diseador de software te ha mostrado un esquema del nuevo sistema de partes de ordenador que est a punto de crear. En lo alto de la jerarqua est una clase llamada Ordenador y bajo ella hay dos clases hijas. Una se llama LinuxPC y la otra WindowsPC. La principal diferencia entre las dos es que una ejecuta el Sistema Operativo Linux y la otra ejecuta el sistema Windows (desde luego otra diferencia es que una necesita ser rearrancada constantemente y la otra funciona fiablemente). Bajo WindowsPC hay dos subclases, una llamada Server y la otra llamada Workstation. Cmo valoraras el trabajo de tu diseador?
1)Dar la luz verde para posteriores diseos usando el esquema actual 2)Pedir un rediseo de la jerarqua cambiando el Sistema Operativo a un campo de la clase antes que a un tipo de clase 3)Pedir que la opcin WindowsPC se elimine ya que pronto quedar obsoleta 4) Cambiar la jerarqua para eliminar la necesidad de la superflua clase Ordenador.

Pregunta 4) Dada la siguiente clase


class Base{ int Edad=33; }

Cmo mejoraras la clase con respecto al acceso al campo Edad?


1)Definir la variable Edad como privada 2)Definir la variable Edad como protegida 3)Definir la variable Edad como privada y crear un mtodo get que la devuelva y un mtodo set que la actualice 4)Definir la variable Edad como protegida y crear un mtodo set que la devuelva y un mtodo get que la actualice

Pregunta 5) Cules de los siguientes son beneficios de la encapsulacin?


1)Todas las variables pueden manipularse como objetos en vez de con primitivas 2)Haciendo todas las variables protegidas estn protegidas de una corrupcin accidental 3)Se puede cambiar la implementacin de una clase sin estropear el cdigo que la usa 4)Hacer todos los mtodos protegidos previene la corrupcin accidental de datos.

132

javaHispano. Tu comunidad, tu lenguaje. Pregunta 6) Nombre tres caractersticas principales de la Programacin Orientada a Objetos:
1)Encapsulacin, ligadura dinmica, polimorfismo 2)Polimorfismo, sobrecarga, redefinicin 3)Encapsulacin, herencia, ligadura dinmica 4)Encapsulacin, herencia, polimorfismo

Pregunta 7) Como implementas la encapsulacin en una clase?


1)Haciendo todas las variables protegidas y slo permitiendo el acceso va mtodos 2)Haciendo todas las variables privadas y slo permitiendo el acceso va mtodos 3)Asegurando que todas las variables son representadas por clases envolventes 4)Asegurando que todas las variables son accedidas a travs de mtodos de una clase ancestra.

Respuestas
Respuesta 1)
1) fecha de registro 4) diagnstico

La fecha de registro es razonable como campo adicional para un paciente, y el diseo especficamente dice que un paciente debera tener un diagnstico. Como el paciente es un tipo de persona, debera tener disponibles los campos edad y sexo (asumiendo que no fueran declarados como privados). Respuesta 2) 2)
RType.amethod 99 RType.amethod

Si esta respuesta te parece improbable, intenta compilar y ejecutar el cdigo. La razn es que este cdigo crea una instancia de la clase Rtype pero la asigna a una referencia a la clase Base. En esta situacin una referencia a cualquiera de los campos como es el caso de ise referir al valor en la clase Base, pero una llamada a un mtodo har referencia al mtodo en la clase Rtype antes que a su manejador de referencia. Respuesta 3) 2) Pedir un rediseo de la jerarqua cambiando el Sistema Operativo a un campo de la clase antes que a un tipo de clase Respuesta 4) 133

Tutorial para el examen de certificacin: SCJP 1.2 3) Definir la variable Edad como privada y crear un mtodo get que la devuelva y un mtodo set que la actualice. Respuesta 5) 3) Se puede cambiar la implementacin de una clase sin estropear el cdigo que la usa. Respuesta 6) 4) encapsulacin, herencia, polimorfismo Me hicieron esta pregunta en una entrevista de trabajo una vez. Consegu el trabajo. No puedes tener la seguridad de encontrar algo as en el examen, pero bien viene saberlo. Respuesta 7) 2)Haciendo todas las variables privadas y slo permitiendo el acceso va mtodos Otras Fuentes para este tema: Este tema se cubre en el Tutorial de Sun en: http://java.sun.com/docs/books/tutorial/java/concepts/index.html Richard Baldwin cubre este tema en: http://www.Geocities.com/Athens/Acropolis/3797/Java004.htm#an initial description of oop (Esto es material general sobre OOP ms que sobre "es un" / "tiene un") Jyothi Krishnan sobre este tema en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html#obj19 Java 1.1 Unleashed http://www.itlibrary.com/reference/library/1575212986/htm/ch05.htm (Ver la seccin sobre encapsulacin) http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html - obj19

134

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2)
Escribir cdigo para invocar mtodos sobrecargados y sobrescritos; constructores paternos o sobrecargados y describir el efecto de invocar estos mtodos.

Comentario sobre el objetivo


Los trminos overloaded (sobrecargado) y overriden (sobrescrito, redefinido o sobrepasado) son en ingls lo bastante similares como para llevar a la confusin. Mi forma de recordarlo es imaginar que algo que ha sido redefinido o sobrepasado es algo a lo que le ha pasado encima un vehculo pesado y ya no existe por s mismo. Algo que ha sido sobrecargado todava se mueve pero est cargado con montones de funcionalidades que le causan un gran esfuerzo. Esto es slo un pequeo truco para distinguir a ambos, no tiene ninguna relacin con la realidad del funcionamiento de Java.

Sobrecarga de mtodos
La sobrecarga de mtodos es un truco del compilador para permitirte usar el mismo nombre para realizar acciones distintas dependiendo de los parmetros. Entonces, imagina que ests diseando la interfaz para un sistema que haga exmenes de certificacin de Java falsos (quin podra saber?). Una respuesta podra venir como un entero, un booleano o una cadena de texto. Podras crear una versin del mtodo para cada tipo de parmetro y darle el nombre correspondiente como:
marcarespuestaboolean(boolean respuesta){ } marcarespuestaint(int respuesta){ } marcarespuestaString(String respuesta){ }

Esto funcionara pero supone que los futuros usuarios de tus clases tendrn que saber ms nombres de mtodos de lo estrictamente necesario. Sera ms til si pudieras usar un solo nombre de mtodo y el compilador resolviera a qu cdigo llamar segn el tipo y el nmero de parmetros de la llamada. Este es el ncleo de la sobrecarga de mtodos, parte de lo cual se conoce como polimorfismo. No hay palabras claves que recordar para sobrecargar mtodos, slo se crean mltiples mtodos con el mismo nombre pero distinto nmero y/o tipo de parmetros. Los nombres

135

Tutorial para el examen de certificacin: SCJP 1.2 de los parmetros no son importantes pero el nmero y los tipos s deben ser diferentes. As, el siguiente es un ejemplo de un mtodo marcarespuesta sobrecargado
void marcarespuesta(String respuesta){ } void marcarespuesta(int respuesta){ }

El siguiente no es un ejemplo de sobrecarga y causar un error en tiempo de compilacin indicando una declaracin duplicada de mtodo.
void marcarespuesta(String respuesta){ } void marcarespuesta(String titulo){ }

El tipo de retorno no forma parte de la identificacin en cuanto a la sobrecarga. Por tanto, cambirselo a uno de los mtodos de arriba por int an producir un error en tiempo de compilacin, pero esta vez indicando que no se puede redefinir un mtodo con un tipo de retorno distinto. Los mtodos sobrecargados no tienen restricciones en cuanto a qu excepciones se pueden hacer lanzar (hacer throw). Esto s es algo a tener en cuenta con la redefinicin.

Los mtodos se diferencian slo en el nmero, tipo y orden de los parmetros, no en el tipo de retorno del mtodo

Sobrescritura de mtodos
Sobrescribir un mtodo significa que se reemplaza su funcionalidad entera. Se hace en una clase hija con un mtodo definido en una clase padre. Para redefinir un mtodo se define uno nuevo en la clase hija con exactamente la misma identificacin que el de la clase padre. Esto tiene el efecto de obscurecer el mtodo en la clase padre y de que la funcionalidad de ste ya no sea directamente accesible. Java proporciona un ejemplo de redefinicin en el caso del mtodo equals que cada clase hereda de la gran clase antecesora Object. La versin heredada de equals

136

javaHispano. Tu comunidad, tu lenguaje. simplemente compara a qu lugar de la memoria referencia la instancia de la clase. A menudo esto no es lo que se desea, particularmente en el caso de un String. Para una cadena generalmente querras una comparacin carcter a carcter para ver si las dos cadenas son la misma. Para permitir esto la versin de equals que viene con String es una versin redefinida que efecta esta comparacin carcter a carcter.

Invocando constructores de clases base


Un constructor es un mtodo especial que se ejecuta automticamente cada vez que se crea una instancia de una clase. Java sabe que un mtodo es un constructor porque tiene el mismo nombre que la clase misma y no tiene valor de retorno. Un constructor puede recibir parmetros como cualquier otro mtodo y puedes necesitar diferentes parmetros segn cmo quieras que la clase se inicialice. As si te fijas en el ejemplo en la clase Button del paquete AWT su constructor est sobrecargado para que tenga dos versiones.

Button() Button(String label)

As, puedes crear un botn sin etiqueta y drsela despus, o usar la opcin ms comn y asignarle la etiqueta en el momento de la creacin.

Sin embargo, los constructores no se heredan, as que si quieres sacar un constructor til de una clase ancestro no est disponible por defecto. As, el siguiente cdigo no compilar
class Base{ public public } Base(){} Base(int i){}

public class MiRedef extends Base{ public static void main(String argvp[]){ MiRedef m = new MiRedef(10);// NO compilar } }

La palabra mgica que necesitas para acceder a un constructor de un ancestro es super. Esta palabra clave se puede usar como si fuera un mtodo y recibir parmetros que concuerden con la versin deseada del constructor padre. En este ejemplo modificado del cdigo previo se usa la palabra clave super para llamar a la versin con el entero del constructor en la clase base y el cdigo se compila sin problemas.

137

Tutorial para el examen de certificacin: SCJP 1.2


class Base{ public Base(){} public Base(int i){} } public class MiRedef extends Base{ public static void main(String arg[]){ MiRedef m = new MiRedef(10); } MiRedef(int i){ super(i); } }

Invocando constructores con this()


De la misma forma que se puede llamar al constructor de una clase base usando super() se puede llamar a otro constructor de la clase en cuestin usando this como si fuera un mtodo. As en el ejemplo anterior se podra definir otro constructor de la siguiente manera
MiRedef(String s, int i){ this(i); }

Tanto this como super se pueden llamar en la primera lnea desde un constructor, pero no ambos a la vez.

Como habrs adivinado esto llamar al otro constructor de la clase actual que toma un solo entero como parmetro. Si usas super() o this() en un constructor debe ser la primera llamada a un mtodo. Como slo uno de los dos puede ser el primer mtodo llamado, no puedes usar a la vez super() y this() en un constructor.

As, lo siguiente causar un error en tiempo de compilacin.


MiRedef (String s, int i){ this(i); super();// Causa un error en tiempo de compilacin. }

138

javaHispano. Tu comunidad, tu lenguaje. Basndonos en el conocimiento de que los constructores no se heredan, debe resultar obvio que la redefinicin es irrelevante. Si tienes una clase llamada Base y creas una clase hija que la extiende, para la clase que la extiende redefinir el constructor debe tener el mismo nombre. Esto causara un error en tiempo de compilacin. Aqu hay un ejemplo de esta jerarqua absurda.
class Base{} class Base extends Base{} // Error en tiempo de compilacin!

El constructor y la jerarqua de clases


Los constructores siempre se llaman hacia abajo desde lo alto de la jerarqua. Es muy probable que en el examen te hagan preguntas relativas a una jerarqua de clases con varias llamadas a this y super y tengas que elegir cul ser el resultado. Ten cuidado con las preguntas en las que tienes una jerarqua compleja que resulta irrelevante a causa de un constructor que hace una llamada tanto a this como a super y por tanto se produce un error en tiempo de compilacin.

Los constructores se llaman desde la base (ancestro) de la jerarqua hacia abajo

Sea el siguiente ejemplo:

class Mamfero{ Mamfero (){ System.out.println("Creando Mamfero "); } } public class Humano extends Mamfero { public static void main(String argv[]){ Humano h = new Humano(); } Humano(){ System.out.println("Creando Humano"); } }

139

Tutorial para el examen de certificacin: SCJP 1.2 Cuando se ejecute este cdigo la cadena Creando Mamfero aparece primero debido a la llamada implcita al constructor sin argumentos de la base de la jerarqua.

Pregunta 1)

Dada la siguiente definicin de clase, cul de los siguientes mtodos podra colocarse legalmente despus del comentario con la palabra comentada //Aqu?

public class Rid{ public void amethod(int i, String s){} //Aqu }

1) public void amethod(String s, int i){} 2) public int amethod(int i, String s){} 3) public void amethod(int i, String mystring){} 4) public void Amethod(int i, String s) {}

Pregunta 2)

Dada la siguiente definicin de clase, cul de los siguientes mtodos podra colocarse legalmente despus del comentario con la palabra comentada //Aqu?

140

javaHispano. Tu comunidad, tu lenguaje.


public class MyOver extends Base{ public static void main(String arg[]){ MyOver m = new MyOver(10); } MyOver(int i){ super(i); } MyOver(String s, int i){ this(i); //Aqu } }

1) MyOver m = new MyOver(); 2) super(); 3) this("Hola",10); 4) Base b = new Base(10);

Pregunta 3)

Dada la siguiente definicin de clases:

class Mamfero{ Mamfero (){ System.out.println("Mamfero "); } } class Perro extends Mamfero { Perro(){ System.out.println("Perro"); } } public class Collie extends Perro { public static void main(String argv[]){ Collie c = new Collie(); } Collie(){ this("Buen Perro"); System.out.println("Collie");

141

Tutorial para el examen de certificacin: SCJP 1.2


} Collie(String s){ System.out.println(s); } }

Cul ser la salida? 1)Error al compilar 2)Mamfero, Perro, Buen Perro, Collie 3)Buen Perro, Collie, Perro, Mamfero 4)Buen Perro Collie Pregunta 4)
Cules de las siguientes sentencias son verdaderas?

1)Los constructores no se pueden heredar 2)Un constructor se puede sobrescribir 3)Un constructor padre se puede invocar utilizando this
4)Cualquier mtodo puede contener una llamada a this o super

Pregunta 5) Qu pasara cuando intentes compilar y ejecutar el siguiente cdigo?


class Base{ public void amethod(int i, String s){ System.out.println("Base amethod"); } Base(){ System.out.println("Base Constructor"); } } public class Child extends Base{ int i; String Parm="Hello"; public static void main(String argv[]){ Child c = new Child(); c.amethod(); } void amethod(int i, String Parm){

142

javaHispano. Tu comunidad, tu lenguaje.


super.amethod(i,Parm); } public void amethod(){} }

3)Mostrar Base Constructor super.amethod

1)Error al compilar 2)Error causado por la sintaxis ilegal en: super.amethod(i,Parm); 4)Error causado por los nombres incorrectos de los parmetros en la llamada a;

Pregunta 6) Cul ser la salida del siguiente cdigo si intentas compilarlo y ejecutarlo?
class Mammal{ Mammal(){ System.out.println("Four"); } public void ears(){ System.out.println("Two"); } } class Dog extends Mammal{ Dog(){ super.ears(); System.out.println("Three"); } } public class Scottie extends Dog{ public static void main(String argv[]){ System.out.println("One"); Scottie h = new Scottie(); } }

1) One, Three, Two, Four 2) One, Four, Three, Two 3) One, Four, Two, Three 4) Error al compilar

Respuestas
Respuesta 1)

143

Tutorial para el examen de certificacin: SCJP 1.2

1) public void amethod(String s, int i){} 4) public void Amethod(int i, String s) {} La letra A mayscula en Amethod nos indica que es un mtodo distinto a amethod Respuesta 2) 4) Base b = new Base(10); Cualquier llamada a this o super debe estar en la primera lnea del constructor. Como en el mtodo ya se utiliz this, ninguna otra opcin puede ser utilizada Respuesta 3) 2) Mamfero, Perro, Buen Perro, Collie Respuesta 4) 1)Los constructores no se pueden heredar Los constructores padres con invocados utilizando this o super Repuesta 5) 1)Error al compilar Esto causa un error que indica algo como lo siguiente: no puedes sobrescribir mtodos para hacerlos privados, amethod en la clase Base esta definido como privado, y en Child al no ponerle modificador de acceso antes de void, estas intentando alterar el modificador public. Respuesta 6) 3) One, Four, Two, Three Las clases son creadas desde la raz del la jerarqua de herencia hacia abajo.

144

javaHispano. Tu comunidad, tu lenguaje. Otras Fuentes para este tema: Este tema es cubierto el Tutorial de SUN en: http://java.sun.com/docs/books/tutorial/java/javaOO/methoddecl.html Richard Baldwin cubre este tema en: http://www.Geocities.com/Athens/Acropolis/3797/Java004.htm#polymorphism in general (Material sobre POO concerniente a "es un" y tiene un") Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html#obj20

145

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 3)
Escribir cdigo que construya instancias de una clase en concreto, incluyendo clases de nivel superior, clases internas, clases internas estticas y clases annimas.

Nota sobre este objetivo


Parte de este material es cubierto en la seccin 4.

Instanciando una clase


Concretamente, las clases pueden ser instanciadas como una referencia a un objeto (tambin llamada simplemente objeto). De esta manera, una clase abstracta no puede ser instanciada y por lo tanto no se puede crear una referencia a un objeto. Recuerda que una clase que contiene un mtodo abstracto es abstracta por si misma y no puede ser instanciada. La manera para instanciar una clase es usando la palabra clave new. Tpicamente se utiliza de la siguiente manera:
Button b = new Button();

La sintaxis indica que la variable name es del tipo Button y contiene una referencia a una instancia de Button. Sin embargo aunque el tipo de la referencia es frecuentemente el mismo que el tipo de la clase instanciada, esto no necesariamente tiene que se as. El siguiente cdigo es valido:
Object b = new Button();

La sintaxis anterior indica que el tipo de la referencia de b es Object en lugar de Button.


La declaracin e instanciacin puede no ocurrir en la misma lnea, As, puedes construir una instancia de una clase de la siguiente manera: Button b; b=new Button();

Clases internas

146

javaHispano. Tu comunidad, tu lenguaje. Las clases internas fueron introducidas con la liberacin del JDK 1.1. Las clases internas permiten definir clases dentro de otras clases, en ocasiones estas clases son conocidas como clases anidadas. Son usadas extensivamente a partir del modelo de eventos de JDK 1.1. Con certeza encontraras en el examen preguntas acerca de las clases anidadas y del alcance de ellas. Este es un ejemplo sencillo:
class Nest { class NestIn{} }

La salida cuando este cdigo se compile sern dos archivos .class. El primero, que es el que esperas es:
Nest.class

el otro es
Nest$NestIn.class

Esto ilustra que el anidamiento de clases es generalmente una convencin para nombrar clases en lugar de una nueva clasificacin de archivos .class. Las clases internas te permite hacer una agrupacin lgica de clases. Tambin tienen beneficios para controlar el alcance de las variables.

Clases Anidadas de nivel Superior (Top Level)


Una clase anidada de nivel superior es un miembro esttico contenido dentro de una clase de nivel superior.
class Nest{ static class NestIn{} }

Este tipo de anidamiento es usado frecuentemente para agrupar de una manera sencilla clases que guardan una relacin entre si. Debido a que la clase es esttica no requiere una instancia de la clase externa para existir.

Clases Miembro
Veo una clase miembro como una clase interna ordinaria. Una clase miembro es semejante a otros miembros de una clase, debes instanciar la clase exterior antes de crear una instancia de la clase interna. Debido a la necesidad que tiene la clase interna de ser asociada con una instancia de la clase externa, Sun introduce una nueva sintaxis para 147

Tutorial para el examen de certificacin: SCJP 1.2 permitir la creacin simultnea de una instancia de la clase externa y al mismo tiempo la creacin de la clase interna. Es de esta forma:
Outer.Inner i = new Outer().new Inner();

Para darle sentido a esta nueva sintaxis, intenta pensar que la primera aparicin de la palabra clave new es usada en el ejemplo anterior para designar la pertenencia a la instancia actual this. As, podras cambiar la lnea que crea la instancia de sta clase y leer lo siguiente:
Inner i = this.new Inner();

Debido a que una clase miembro no puede existir sin un instancia de la clase exterior, sta puede tener acceso a las variables de la clase exterior.

Clases creadas dentro de mtodos


Un nombre ms correcto para este tipo de clases es clase local.

Las clases locales solo pueden acceder a campos finales o parmetros del mtodo que la contiene

Una clase local es visible nicamente dentro del bloque de cdigo del mtodo. El cdigo dentro de la clase local puede usar nicamente variables locales que tengan el modificador final en el bloque del mtodo o parmetros del mtodo. Es muy probable que te encuentres con preguntas de este tipo en el examen.

Clases annimas
Tu primera reaccin con la idea de una clase annima debe ser "por qu querra yo tener una clase sin nombre? y cmo podra referirme a una clase si no tiene nombre?" Para contestar estas preguntas, considera lo siguiente. Podras estar en una situacin en donde constantemente tienes que pensar en nombres para instancias de clases en donde el nombre es por si mismo evidente. Por ejemplo en el manejo de eventos las dos cosas mas importantes que necesitas saber para manejar el evento son: el evento que se va a manejar y el nombre del componente que esta utilizando dicho manejador. Tener el nombre de la instancia la clase que maneja el evento no aporta mucho valor.

148

javaHispano. Tu comunidad, tu lenguaje. Acerca de la pregunta de como puedes hacerle referencia, pues, simplemente no puedes y si necesitas referirte a la clase por su nombre, entonces no deberas crear una clase annima. La falta del nombre de la clase tiene efectos adicionales, como el hecho de que no puedes darle a la clase annima un constructor.

Las clases annimas no pueden tener constructores

Este es un ejemplo de una clase interna annima:


class Nest{ public static void main(String argv[]){ Nest n = new Nest(); n.mymethod(new anon(){}); } public void mymethod(anon i){} } class anon{}

Nota que la declaracin y definicin de la clase annima se realiza dentro de los parntesis de la llamada a mymethod.

Pregunta 1) Cules de las siguientes afirmaciones son verdaderas? 1)Una clase definida dentro de un mtodo puede nicamente acceder mtodos estticos del mtodo que la contiene 2)Una clase definida dentro de un mtodo puede nicamente acceder variables finales del mtodo que la contiene 3)Una clase definida dentro de un mtodo no puede acceder a algn campo del mtodo que la contiene

149

Tutorial para el examen de certificacin: SCJP 1.2 4)Una clase definida dentro de un mtodo puede acceder cualquier campo accesible del mtodo que la contiene Pregunta 2) Cules de las siguientes afirmaciones son verdaderas? 1)Una clase annima no puede tener un constructor 2)Una clase annima puede ser creada nicamente dentro del cuerpo de un mtodo 3)Una clase annima puede nicamente acceder a campos estticos del mtodo que la contiene 4)El tipo de clase de una clase annima puede ser obtenido utilizando el mtodo
getName

Pregunta 3) Cules de las siguientes afirmaciones son verdaderas? 1)Una clase interna no puede ser marcada como privada 2) Una instancia de una clase anidada de nivel superior puede crearse sin necesidad de crear una instancia de la clase que la contiene 3)Un archivo que contenga una clase externa y una interna nicamente producir un nico archivo .class 4) Para crear una instancia de una clase miembro se requiere crear una instancia de la clase que la contiene Respuestas Respuesta 1) 2)Una clase definida dentro de un mtodo puede nicamente acceder variables finales del mtodo que la contiene Respuesta 2) 1)Una clase annima no puede tener un constructor Respuesta 3) 2) Una instancia de una clase anidada de nivel superior puede crearse sin necesidad de crear una instancia de la clase que la contiene 4) Para crear una instancia de una clase miembro se requiere crear una instancia de la clase que la contiene

150

javaHispano. Tu comunidad, tu lenguaje. Una clase anidada genera por si misma un archivo .class, usando el formato: Outer$Inner.class Una clase anidada de nivel superior es como una clase esttica as que no requiere una instancia de la clase que la contiene. Una clase miembro es como una clase no esttica, por consiguiente se requiere una instancia de la clase que la contiene,.

Otras Fuentes para este tema: Tutorial de Sun: http://java.sun.com/docs/books/tutorial/java/more/nested.html Richard Baldwin http://www.geocities.com/Athens/7077/Java094.htm Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec6.html#obj21

151

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 7. Threads
Objetivo 1)
Escribir cdigo para definir, instanciar y comenzar nuevos threads usando java.lang.Thread y java.lang.Runnable.

Qu es un Thread ?
Los Threads son procesos ligeros que aparentan correr en paralelo con tu programa principal. A diferencia de los procesos un thread comparte memoria y datos con el resto del programa. La Palabra Thread es una contraccin de Thread de ejecucin (Hilo de ejecucin), puedes imaginar una cuerda, a la cual le has deshilachado el final y has tomado un hilo. El hilo todava es parte de la misma cuerda, pero puede ser separado de la principal y ser manipulado por si solo. Un ejemplo de donde pueden ser tiles los threads, es en la impresin. Cuando das un click en el botn imprimir, probablemente no quieras que el programa principal se detenga hasta que finalice la impresin. Lo deseable, seria que el proceso de impresin comenzara a ejecutarse en segundo plano y te permitiera continuar usando la parte principal del programa. Tambin sera til si el programa principal pudiera responder si el hilo (thread) de impresin encontrara algn problema. Un ejemplo comn utilizado para ilustrar los threads es el crear una aplicacin GUI que lanzara una pelota rebotando cada vez que un botn es presionado. A diferencia de otros lenguajes el threading esta embebido en el corazn de Java, mucho de l al nivel de la ultima clase ancestro llamada Object.

Las dos formas de crear un Hilo (Thread)


De las dos maneras de crear un Hilo (algunos documentos ocupan la palabra hebra en lugar de hilo) el uso de Runnable es probablemente el mas comn, pero debes de conocer las dos para propsitos del examen. El siguiente es un ejemplo de una clase creada con la interface Runnable.
class MyClass implements Runnable { public void run() { //Blank Body } }

Creando el hilo de ejecucin.


MyClass mc = new MyClass();

152

javaHispano. Tu comunidad, tu lenguaje.

Cualquier clase que implemente una interfase debe crear un mtodo correspondiente por cada uno de los que se encuentren en la interfase. No es necesario que los mtodos realicen algo, pueden tener el cuerpo del mtodo en blanco, pero deben estar ah. De esta manera inclu el mtodo run incluso en este pequeo ejemplo, ya que si implementas Runnable debes incluir el mtodo run No incluir el mtodo run causara un error en tiempo de compilacin. Para hacer algo til cuando se crea un hilo de ejecucin de una clase deberas de, por supuesto, colocar algo de cdigo donde puse : //Blank body La otra manera de crear un hilo es crear una clase que descienda de Thread. Esto es fcil de hacer pero significa que no puedes heredar de ninguna otra clase, debido a que Java solo soporta herencia simple. De esta manera, si estas creando un botn no le puedes agregar threading a de esta manera porque un botn hereda de la clase AWT Button y eso utiliza tu nica opcin de herencia. Existe debate sobre cual de las dos formas de crear un hilo es verdaderamente ms orientada a objetos, pero no necesitas llegar a esa conclusin para propsitos del examen.

Instanciando e Iniciando un hilo.


Aunque el cdigo que se ejecuta en tu thread esta en un mtodo llamado run, no necesitas llamar a este mtodo directamente, en vez de eso llamas al mtodo start de la clase Thread. La interfase Runnable no contiene un mtodo start, entonces, para llegar a este mtodo y a los otros tiles mtodos para threads (sleep, suspend, etc), pasas tu clase con la interfase Runnable como el constructor de una instancia de la clase Thread. De este modo para hacer que el hilo se ejecute desde una clase que implemente
Runnable debers llamar lo siguiente: MyClass mc = new MyClass(); Thread t = new Thread(mc); t.start();

De nuevo observa que fue una llamada al mtodo start, no una llamada al mtodo run, aunque es el cdigo en el mtodo run en tu clase el que actualmente se ejecuta. Aunque es el mtodo run el que ejecuta, un hilo se inicia a travs del mtodo start.

153

Tutorial para el examen de certificacin: SCJP 1.2

Si creas una clase que sea una subclase de Thread simplemente tienes que llamar al mtodo start. El inconveniente de heredar de la clase Thread, es que debido al soporte de herencia simple no puedes heredar funcionalidad de ninguna otra clase.

Preguntas Pregunta 1) Qu ocurrir cuando intentes compilar y ejecutar el siguiente cdigo?


public class Runt implements Runnable{ public static void main(String argv[]){ Runt r = new Runt(); Thread t = new Thread(r); t.start(); } public void start(){ for(int i=0;i<100;i++) System.out.println(i); }

1)Compila y tiene como salida una cuenta de 1 a 99 2)Compila pero no tiene salida 3)Error en tiempo de compilacin: La clase Runt es una clase abstracta. No puede ser instanciada 4)Error en tiempo de compilacin, el mtodo start no puede ser llamado directamente Pregunta 2) Cules de las siguientes frases es cierta? 1)Heredar directamente de la clase Thread te da acceso a ms funcionalidad de las capacidades de tareas de Java que implementar la interfase Runnable 2)Usar la interfase Runnable significa que no tienes que crear una instancia de la clase Thread y llamar al mtodo run directamente.

154

javaHispano. Tu comunidad, tu lenguaje. 3)Utilizando ambas, La interfase Runnable y heredar de la clase Thread requiere el llamado al mtodo start para comenzar la ejecucin 4)La interfase Runnable requiere nicamente implementar un mtodo, que es llamado
run

Pregunta 3) Qu ocurrir cuando intentes compilar y ejecutar el siguiente cdigo?


public class Runt extends Thread{ public static void main(String argv[]){ Runt r = new Runt(); r.run(); } public void run(){ for(int i=0;i<100;i++) System.out.println(i); }

1)Compila y tiene como salida una cuenta de 1 a 99

2)Compila pero no tiene salida 3)Error en tiempo de compilacin: La clase Runt es una clase abstracta. No puede ser instanciada 4)Error en tiempo de compilacin, el mtodo start no ha sido definido Pregunta 4) Cules de las siguientes frases es cierta? 1)Para implementar el Threading en un programa debes importar la clase
java.io.Thread

2)El cdigo que se ejecuta cuando inicias un hilo es colocado en el mtodo run 3)Los Threads pueden compartir datos entre unos y otros 4)Para comenzar la ejecucin de un Thread, llamas al mtodo start y no al mtodo run.

Respuestas Respuesta 1) 3) Error en tiempo de compilacin: La clase Runt es una clase abstracta. No puede ser instanciada

155

Tutorial para el examen de certificacin: SCJP 1.2 La clase implementa Runnable pero no define el mtodo run. Respuesta 2) 3) Usar la interfase Runnable significa que no tienes que crear una instancia de la clase Thread y llamar al mtodo run directamente. 4) La interfase Runnable requiere nicamente implementar un mtodo, que es llamado
run

Respuesta 3) 1)Compila y tiene como salida una cuenta de 1 a 99 Sin embargo, observa que este cdigo no inicia la ejecucin del hilo y el mtodo run no debe ser llamado de esta forma. Respuesta 4) 2)El cdigo que se ejecuta cuando inicias un hilo es colocado en el mtodo run 3)Los Threads pueden compartir datos entre unos y otros 4)Para comenzar la ejecucin de un Thread, llamas al mtodo start y no al mtodo run. No necesitas importar ninguna clase ya que el Threading es una parte integral de Java.

Otras Fuentes sobre este tema Este tema esta cubierto en el tutorial de sun en http://java.sun.com/docs/books/tutorial/essential/threads/customizing.html Richard Baldwin cubre este tema en http://www.Geocities.com/Athens/Acropolis/3797/Java058.htm#two ways to thread Jyothi Krishnan sobre este tema en http://www.geocities.com/SiliconValley/Network/3693/obj_sec7.html#obj22 La parte de Threads del Tutorial de Elliot Rusty Harold http://www.ibiblio.org/javafaq/course/week11/index.html

156

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2)
Reconocer las condiciones que puedan impedir que un Thread se ejecute

Comentario de este objetivo


La expresin impedir que un thread se ejecute es ligeramente ambigua, significa que un hilo ha sido pausado deliberadamente, o tambin incluye hilos que han muerto?. Se dice que un hilo a sido bloqueado cuando se le ha impedido ejecutarse.

Razones por las que un thread puede ser bloqueado


Un hilo puede ser bloqueado por que:
Ha sido puesto a dormir por una cantidad de tiempo Ha sido suspendido por una llamada al mtodo suspend() y estar bloqueado hasta una llamada al mtodo resume() El hilo ha sido suspendido por una llamada al mtodo wait(), y se volver ejecutable con un mensaje notify o notifyAll.

Para propsitos del examen sleep(), y wait/notify son probablemente las ms importantes de las situaciones por las que un hilo pueda ser bloqueado. El mtodo sleep es esttico y detiene la ejecucin de un hilo por un nmero fijo de milisegundos. Existe una versin que supuestamente debe pausar por un nmero fijo de nanosegundos, aunque encuentro difcil de creer que alguien pueda trabajar en una mquina o implementacin de Java que trabaje a ese nivel de precisin. El siguiente es un ejemplo para poner a dormir un hilo, nota como el mtodo sleep lanza InterruptedException. El hilo:
public class TSleep extends Thread{ public static void main(String argv[]){ TSleep t = new TSleep(); t.start(); } public void run(){ try{ while(true){ this.sleep(1000); System.out.println("looping while"); } }catch(InterruptedException ie){} }

} 157

Tutorial para el examen de certificacin: SCJP 1.2

Con la salida de Java 2, los mtodos de la clase Thread : stop, suspend y resume han quedado obsoletos (depracated, no se recomienda que se usen y al utilizarlos se enva una advertencia en tiempo de compilacin). Las notas del JDK indican lo siguiente: //Quote
Obsoleto. Este mtodo ha sido censurado, ya que es inherentemente propenso a crear deadlocks. Si el hilo objetivo mantiene un bloqueo sobre el monitor protegiendo un recurso de sistema crtico cuando queda suspendido, ningn otro hilo puede acceder a este recurso hasta que el hilo objetivo es reiniciado. Si el Hilo que intenta resumir al hilo objetivo intenta realizar un bloqueo antes de llamar a resume(), ocurre un deadlock. Tales deadlocks tpicamente se manifiestan como procesos congelados. Para mas informacin vea Por que son Obsoletos los mtodos: Thread.stop, Thread.suspend y Thread.resumen?

//End Quote Una fuente generalmente confiable (Kathy Kozel) ha indicado que tienes que estar conciente de esto para propsitos del examen. Yo asumir que actualmente no necesitas conocer como usarlos. El bloqueo del Thread va el protocolo wait/notify es cubierto en el siguiente tema

Pregunta 1) Qu ocurrir cuando intentes compilar y ejecutar el siguiente cdigo?


public class TGo implements Runnable{ public static void main(String argv[]){ TGo tg = new TGo(); Thread t = new Thread(tg); t.start(); } public void run(){ while(true){ Thread.currentThread().sleep(1000); System.out.println("looping while"); } } }

1)Compila y no tiene salida

158

javaHispano. Tu comunidad, tu lenguaje. 2)Compila y tiene como salida el texto looping while repetidamente 3)Compila y tiene como salida el texto looping while una sola vez 4)Error en tiempo de compilacin Pregunta 2) Cul de las siguientes formas es una manera recomendada para que un Thread pueda ser bloqueado? 1)sleep() 2)wait/notify 3)suspend 4)pause Pregunta 3) Cules de las siguientes frases son verdaderas? 1)El mtodo sleep toma parmetros del Hilo y el nmero de segundos que debe dormir 2)El mtodo sleep toma un solo parmetro que indica el nmero de segundos que debe dormir 3)El mtodo sleep toma un solo parmetro que indica el nmero de milisegundos que debe dormir 4)El mtodo sleep es un mtodo esttico de la clase Thread Respuestas Respuesta 1) 4 )Error en tiempo de compilacin El mtodo sleep lanza InterruptedException y de esta manera este cdigo no compilara hasta que el ciclo while quede envuelto en un bloque try/catch Respuesta 2) 1)sleep() 2)wait/notify Para la plataforma Java 2 el mtodo suspend ha sido censurado y de esta manera es vlido pero no recomendado. Respuesta 3)

159

Tutorial para el examen de certificacin: SCJP 1.2 3)El mtodo sleep toma un solo parmetro que indica el nmero de milisegundos que debe dormir 4)El mtodo sleep es un mtodo esttico de la clase Thread Otras Fuentes sobre este tema Este tema esta cubierto en el tutorial de sun en http://java.sun.com/docs/books/tutorial/essential/threads/waitAndNotify.html Richard Baldwin cubre este tema en http://www.geocities.com/Athens/Acropolis/3797/Java058.htm#the notify() and wait() methods Jyothi Krishnan sobre este tema en http://www.geocities.com/SiliconValley/Network/3693/obj_sec7.html#obj23 Comentario de mtodos deprecados en http://java.sun.com/docs/books/tutorial/post1.0/preview/threads.html

160

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 3)
Escribir cdigo utilizando: synchronized, wait, notify, y notifyAll, para proteger el cdigo contra los problemas de acceso concurrente y la comunicacin entre los hilos. Definir la interaccin de bloqueos entre hilos y entre hilos y objetos cuando ejecutan los mtodos: synchronized, wait, notify, y notifyAll.

Por qu necesitaras el protocolo wait/notify?


Una manera de pensar en una utilidad para el protocolo wait/notify es imaginar un dato, por ejemplo una variable entera, e imaginar que es un campo en una base de datos. Si no tienes algn mecanismo de bloqueo en la base de datos existe la posibilidad de corromper los datos. As un usuario podra obtener los datos, realizar un clculo y escribir los datos. Si en el entretanto alguien ms ha recuperado los datos, ha realizado un clculo y lo ha escrito, los segundos clculos de los usuarios se perdern cuando la primera persona escriba en la base de datos.

synchronized
La palabra clave synchronized se utiliza para marcar una sentencia o bloque de cdigo e indicar que nicamente un hilo a la vez puede ejecutar una instancia del cdigo. La entrada al cdigo esta protegida por un supervisor o monitor de bloqueos. Este proceso es implementado por un sistema de bloqueos. Se asigna un bloqueo al objeto y as se asegura que nicamente un hilo a la vez pueda acceder al cdigo. As cuando un hilo empieza a ejecutar un bloque sincronizado este adopta el bloqueo. Cualquier otro hilo no podr ejecutar el cdigo hasta que el primer hilo haya finalizado y liberado el bloqueo. Nota que el bloqueo esta basado en el objeto y no en el mtodo. Para un mtodo la palabra clave synchronized se coloca antes de la definicin del mtodo:
synchronized void amethod() { /* method body */}

Para un bloque de cdigo la palabra va antes de la apertura y cerradura de llaves.


synchronized (ObjectReference) { /* Block body */ }

El valor entre parntesis indica el objeto o clase que necesita obtener el supervisor. Es generalmente ms comn sincronizar un mtodo que un bloque de cdigo.

161

Tutorial para el examen de certificacin: SCJP 1.2 Cuando un bloque de cdigo sincronizado se ejecuta, el objeto es bloqueado y no puede ser llamado por cualquier otro cdigo hasta que el bloqueo sea liberado:
synchronized void first(); synchronized void second();

De esta manera el beneficio por la sincronizacin es mayor que colocando la palabra reservada synchronized antes de un bloque de cdigo.

wait/notify
Adems de tener un bloqueo que puede fijarse y luego liberarse, cada objeto tiene un sistema que le permite hacer una pausa o esperar (wait) aunque otro hilo tome el bloqueo. Esto permite a los hilos poder comunicarse la condicin de disponible para poder ejecutarse

Debido a la naturaleza de herencia simple en Java, cada objeto es hijo de una gran clase ancestro llamado Object desde la cual obtienen la capacidad de comunicacin entre hilos.

wait y notify deben colocarse dentro del cdigo sincronizado para asegurar que el cdigo actual posee al supervisor de threads.

Una llamada a wait dentro del cdigo sincronizado causa que el hilo active su bloqueo y se ponga a dormir. Esto normalmente ocurre para permitir a otro hilo obtener el bloqueo y continuar algn proceso. El mtodo wait es incoherente sin el uso de notify o notifyAll los cuales permiten que el cdigo que est esperando ser notificado pueda despertarse y continuar ejecutndose. Un ejemplo tpico del uso del protocolo wait/notify es para permitir la comunicacin entre los Hilos que aparentemente involucran un ciclo infinito, como el siguiente:
//codigo producto while(true){ try{ wait(); }catch (InterruptedException e) {} } // alguna otra accion va aqui notifyAll();

Como la condicin a evaluar es notoriamente verdadera esta permanecer as, el cdigo a primera vista muestra que el ciclo ser infinito. El mtodo wait sin embargo

162

javaHispano. Tu comunidad, tu lenguaje. efectivamente significa activa el bloqueo sobre el objeto y espera hasta que el mtodo notify o notifyAll sea llamado para liberarlo.

La planificacin de hilos es dependiente de la implementacin y no puede asegurarse una actuacin similar en cada JVM.

A diferencia del resto de Java, la planificacin de hilos es dependiente de la plataforma. Existen dos maneras conocidas para la planificacin de hilos: Preemtive (Preventivo o apropiativo) Time Slicing (Division o fragmentacin de tiempos)

En el primer sistema un programa puede "apropiarse" de otro para conseguir su porcin de tiempo de CPU. En el segundo sistema cada hilo consigue un "pedazo" del tiempo de CPU y entonces se mueve al estado de listo. Esto asegura que un solo hilo no pueda obtener todo el tiempo del CPU. La desventaja es que no puedes estar seguro cunto tiempo tardar un Hilo en ejecutarse. Aunque Java define prioridades para los hilos, de la mas baja 1 a la ms alta que es 10, debes tomar en cuenta que algunas plataformas reconocern estas prioridades con precisin pero otras no. El mtodo notify despertar un hilo que espera ser reactivado por el supervisor de hilos para el objeto. No puedes estar seguro de qu hilo se levantara. Si tienes slo un hilo en espera entonces no tendrs ningn problema. . Si tienes en espera mltiples hilos entonces se levantara el hilo que lleva ms tiempo esperando. Sin embargo no puedes asegurarlo, ya que las prioridades de los hilos influirn en el resultado. Como resultado generalmente se te aconseja que uses notifyAll en lugar de notify para no hacer suposiciones con la planificacin o las prioridades. Por supuesto esto no siempre es posible y tendrs que intentar probar tu cdigo en tantas plataformas como te sea posible.

Preguntas Pregunta 1) Cuales de las siguientes palabras claves indican a un hilo que libere el objeto que esta bloqueando?

163

Tutorial para el examen de certificacin: SCJP 1.2 1) release 2) wait 3) continue 4) notifyAll

Pregunta 2) Cul de las siguientes frases define mejor la funcin de la palabra clave synchronized? 1)Permite que ms de un Hilo acceda a un mtodo simultneamente. 2)Permite que ms de un Hilo obtenga el bloqueo de un Objeto sobre una referencia. 3)Da acceso exclusivo al monitor a las palabras clave notify/notifyAll. 4)Significa que slo un hilo en un momento puede acceder a un mtodo o bloque de cdigo. Pregunta 3) Que pasar cuando intentes compilar y ejecutar el siguiente bloque de cdigo?
public class WaNot{ int i=0; public static void main(String argv[]){ WaNot w = new WaNot(); w.amethod(); } public void amethod(){ while(true){ try{ wait(); }catch (InterruptedException e) {} i++; }//End of while }//End of amethod }//End of class

1)Error en tiempo de compilacin; no hay una llamada a notify() dentro del mtodo 2)Se compila y ejecuta, pero se crea un ciclo infinito dentro del ciclo while 3)Se compila y ejecuta 4)Se genera un error en tiempo de Ejecucin: IllegalMonitorStatException Pregunta 4)

164

javaHispano. Tu comunidad, tu lenguaje.

Cmo puedes especificar qu hilo es el notificado con el protocolo wait/notify 1)Pasando la referencia del objeto como parmetro al mtodo notify 2)Pasando el nombre del mtodo como parmetro al mtodo notify 3)Usando el mtodo notifyAll y pasando la referencia del objeto como referencia 4)Ninguna de las anteriores Pregunta 5) Cules de las siguientes afirmaciones son verdaderas? 1)Java usa un sistema de planificacin basado en la divisin de tiempos para determinar qu Hilo se ejecutar 2)Java usa un sistema apropiativo cooperativo para determinar qu Hilo se ejecutar 3)La planificacin de hilos en Java es dependiente de plataforma y puede variar de una implementacin a otra 4)Tu puedes fijar la prioridad de un hilo en el cdigo Respuestas Respuesta 1) 2) wait Respuesta 2) 4)Significa que slo un hilo en un momento puede acceder a un mtodo o bloque de cdigo. Respuesta 3) 4)Se genera un error en tiempo de Ejecucin: IllegalMonitorStatException El protocolo wait/notify se puede usar solamente dentro del cdigo sincronizado. En este caso la llamada al cdigo no tiene bloqueo sobre el objeto y de esta manera se generar un error en tiempo de compilacin. Respuesta 4) 4)Ninguna de las anteriores

165

Tutorial para el examen de certificacin: SCJP 1.2 El protocolo wait/notify no ofrece un mtodo para especificar que hilo se notificar. Respuesta 5) 3)La planificacin de hilos en Java es dependiente de plataforma y puede variar de una implementacin a otra 4)Tu puedes fijar la prioridad de un hilo en el cdigo

Otras Fuentes para este tema: Este tema es cubierto en tutorial de Sun: http://java.sun.com/docs/books/tutorial/essential/threads/waitAndNotify.html Richard Baldwin Covers lo cubre en: http://www.geocities.com/Athens/Acropolis/3797/Java058.htm Jyothi Krishnan en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec7.html#obj24 Bruce Eckel Thinking in Java Captulo 14

166

javaHispano. Tu comunidad, tu lenguaje.

Seccin 8. El paquete java.awt y su disposicin


Objetivo 1.
Escribir cdigo que use las clases administradoras de disposicin (Layout Manager) y los contenedores (Container) de componentes del paquete java.awt para presentar interfaces graficas de usuario (GUI) con una apariencia especifica, redimensionar su comportamiento y distinguir las responsabilidades entre los administradores de disposicin y los contenedores.

Nota sobre este objetivo


Aunque el enunciado anterior no lo menciona especficamente, este objetivo involucra un nuevo tema comparado con el examen para la versin1.1. ste tema es lo referente al GridBaglayout. Tiene sentido cubrirlo ya que es un administrador de disposicin muy til, pero debido a la utilidad que proporciona puede ser un poco complejo su aprendizaje. Peter va der Linden en su libro "Just Java and Beyond" 3a Edicin lo describe como algo excesivamente complicado y no lo recomienda. Core Java dice: "el uso de GridBagLayout puede ser increblemente complejo". Aunque es complejo utilizarlo de manera manual, varias herramientas de desarrollo como VisualCafe, Visual Age, JBuilder etc etc. lo hacen ms fcil de entender.

Comparando la disposicin de componentes de Java y Visual Basic


Comparada con herramientas como Visual Basic o Delphi, Java usa una filosofa distinta para la disposicin de componentes. La mayora de las herramientas de diseo usan una filosofa basada en la posicin XY de pxeles para colocar un componente. As en Visual Basic puedes tomar una caja de texto de la paleta de componentes y colocarla en una posicin especifica en la forma o rea de diseo, y esa posicin ser fija. En contraste Java usa clases de disposicin para controlar donde ser colocado un componente de acuerdo a la pantalla actual.

La filosofa de los administradores de disposicin


El administrador de disposicin FlowLayout es un buen lugar para empezar ya que es el administrador de disposicin por defecto para los applets. El administrador de disposicin FlowLayout simplemente coloca los componentes sobre el fondo uno despus de otro de izquierda a derecha. Si se acaba el espacio hacia la derecha entonces envuelve los componentes a la prxima lnea El siguiente cdigo crea una aplicacin sencilla y agrega una serie de botones.

167

Tutorial para el examen de certificacin: SCJP 1.2

import java.awt.*; public class FlowAp extends Frame{ public static void main(String argv[]){ FlowAp fa=new FlowAp(); //Change from BorderLayout default fa.setLayout(new FlowLayout()); fa.setSize(400,300); fa.setVisible(true); } FlowAp(){ add(new Button("One")); add(new Button("Two")); add(new Button("Three")); add(new Button("Four")); add(new Button("Five")); add(new Button("Six")); add(new Button("Seven")); add(new Button("Eight")); add(new Button("Nine")); add(new Button("Ten")); }//End of constructor }//End of Application

La siguiente imagen tiene la apariencia por defecto que tendr la aplicacin cuando la ejecutes desde la lnea de comandos: Apariencia por defecto de la aplicacin FlowAp

168

javaHispano. Tu comunidad, tu lenguaje.

Apariencia de la aplicacin FlowAp despus de redimensionar su tamao.

Ten presente que ambas imgenes visualizan exactamente el mismo cdigo Java. Lo nico que ha cambiado es la anchura del Frame. El administrador de disposicin FlowLayout automticamente cambia la disposicin de los componentes cuando el Frame se redimensiona. Si haces el Frame ms pequeo FlowLayout cambiara la disposicin para que los botones se envuelvan alrededor en varias filas. Cuando te encuentras por primera vez con estos administradores de componentes pueden parecerte un poco arbitrarios. Algunas herramientas de desarrollo de aplicaciones como Symantec Visual Caf o Borland/Inprise Jbuilder ofrecen maneras para especificar la posicin de los componentes. Para los propsitos del examen por lo menos debes familiarizarte con el manejo de los administradores de disposicin para la creacin de GUI.

Administradores de disposicin que debes conocer para el examen.


Para el examen, debes conocer los siguientes administradores de disposicin:

FlowLayout BorderLayout GridLayout GridBagLayout

Responsabilidades de los Administradores de Disposicin VS los Contenedores

169

Tutorial para el examen de certificacin: SCJP 1.2 Los contenedores y los administradores de disposicin trabajan en equipo. Los administradores de disposicin generalmente controlan donde se colocarn los componente. Un contenedor controlar la fuente predefinida para estos componentes. Un componente puede asignarse una fuente especifica para s mismo. Te pueden dar un texto que describa la configuracin de un contenedor de componentes y preguntarte que color de fondo y que fuente tendr un botn o una etiqueta al visualizarse.

Curiosidades del administrador BorderLayout


Si agregas mltiples componentes a un contenedor que utiliza el administrador BorderLayout pero no pasas una de sus constantes como parmetro (North, South, etc), puedes conseguir resultados inesperados. Aqu una muestra que ilustra esto:
import java.awt.*; public class FlowAp extends Frame{ public static void main(String argv[]){ FlowAp fa=new FlowAp(); // fa.setLayout(new FlowLayout()); fa.setSize(400,300); fa.setVisible(true); } FlowAp(){ add(new Button("One")); add(new Button("Two")); add(new Button("Three")); add(new Button("Four")); add(new Button("Five")); add(new Button("Six")); add(new Button("Seven")); add(new Button("Eight")); add(new Button("Nine")); add(new Button("Ten")); }//End of constructor }//End of Application

Usando el administrador BorderLayout por defecto

170

javaHispano. Tu comunidad, tu lenguaje. La razn por la que obtienes este botn grande en el centro es que el administrador de disposicin BorderLayout usa un conjunto de coordenadas al colocar los componentes. Divide el rea de la superficie en:

North (Norte) South (Sur) East (Este) West (Oeste) Center (Centro)

Podras suponer que el valor por defecto para los componentes cuando los vas colocando es irse colocando en el sentido de las agujas del reloj alrededor de los puntos de su circunferencia o en algn otro orden similar. En cambio los diseadores decidieron hacer a el centro del rea del esquema el valor por defecto. As en el ejemplo anterior cada botn se ha colocado encima del botn anterior y ha ocupado enteramente el rea disponible. Como resultado la apariencia es que slo tienes un botn, el ltimo agregado. Debido a que el administrador de disposicin BorderLayout slo divide el rea en las cinco coordenadas mencionadas anteriormente, no es el ms utilizado de los administradores de disposicin. Sin embargo necesitas conocerlo para el examen y necesitas ser consciente de que tiene como valor predefinido poner todos los componentes en el centro.

El administrador de disposicin GridLayout


El administrador GridLayout hace aproximadamente lo que esperabas que hiciera. Divide el rea de la superficie en una cuadrcula y cuando agregas componentes los pone uno despus el otro de izquierda a derecha y de arriba hacia abajo. A diferencia de BorderLayout y de FlowLayout ignora cualquier tamao predefinido del componente. Por ejemplo el tamao predefinido de un botn ser el ancho suficiente para mostrar su texto. El administrador FlowLayout intenta asegurarse que un botn mantenga su tamao predefinido. El GridLayout de la nica cosa de la que se preocupa es asegurarse que el componente se ajuste en la cuadrcula El cdigo siguiente pone un conjunto de botones dentro de un Frame que utiliza un GridLayout que ha sido fijado para tener 2 filas y 5 columnas.
import java.awt.*; public class GridAp extends Frame{ public static void main(String argv[]){ GridAp fa=new GridAp(); //definimos el GridLayout con 2 filas y 5 columnas fa.setLayout(new GridLayout(2,5)); fa.setSize(400,300);

171

Tutorial para el examen de certificacin: SCJP 1.2


fa.setVisible(true); } GridAp(){ add(new Button("One")); add(new Button("Two")); add(new Button("Three")); add(new Button("Four")); add(new Button("Five")); add(new Button("Six")); add(new Button("Seven")); add(new Button("Eight")); add(new Button("Nine")); add(new Button("Ten")); }//fin del constructor }//fin de la Aplicacion

Ejemplo con GridLayout

Observa como los botones son alargados para ocupar todo el espacio disponible del Frame.

GridBagLayout
Peter van der Linden en su libro Just Java and Beyond describe al administrador de disposicin GridBagLayout como excesivamente complicado. Core Java solo dice: usar GidBagLayout puede ser increblemente complicado. Aunque es complejo manejarlo manualmente, varias herramientas de desarrollo como Visual Caf, Visual Age, JBuilder, etc. Lo hacen ms fcil de usar, sin tener que entenderlo. JBuilder

172

javaHispano. Tu comunidad, tu lenguaje. modifica fcilmente el mtodo add para incluir los detalles siguientes en una instancia de la clase GridBagLayout.
add(pAps,new GridBagConstraints2(1, GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, 3, 0.0, 0.0,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), -3, 45));

Pero cuando creas tu cdigo manualmente no necesita parecer tan complejo como este. Comentarios de las personas que han realizado el examen indican que las preguntas sobre GridBagLayout no son muy profundas y una comprensin bsica de los distintos campos de la clase GridBagConstraints puede ser adecuada para realizar el examen.
GridBagLayout es un poco parecido a GridLayout slo que las filas de la cuadrcula

pueden tener alturas diferentes, y las columnas pueden tener anchuras distintas. La documentacin de Java2 viene con un applet de demostracin que muestra lo que puede hacerse con el administrador de disposicin GridBagLayout.. Uno de los problemas con el GridBagLayout es que en lugar de estar basado estrictamente en la cuadrcula subyacente, Java intenta definir las celdas de acuerdo a la informacin dada. El administrador de disposicin GridBagLayout usa una clase auxiliar llamada GridBagConstraints que tiene un conjunto de variables miembro que pueden ajustarse para afectar la apariencia de cada componente agregado. Los campos que modificas en la clase GridBagConstraints "sugieren" donde irn los componentes. Una instancia de GridBagConstraints se pasa como un parmetro al mtodo add, en la forma:

add(component, GridBagConstraint);

GridBagConstraints contradice la convencin general en Java, ya que tu esperaras

poder configurarlo con el mtodo:


setFooParam()

Donde FooParam podra ser el valor X/Y o un relleno entre los componentes. En cambio toma la forma:
GridBagLayout gbl=new GridBagLayout(); gbl.weightx=100;

173

Tutorial para el examen de certificacin: SCJP 1.2 Si usas GridBagLayout sin usar la clase GridBagConstraints ste acta un poco como FlowLayout, colocando simplemente uno por uno los componentes en el fondo. He creado un applet de demostracin sencillo con su cdigo fuente que muestra cmo no cambia la apariencia a menos que juegues con los valores de la clase
GridBagConstraints http://www.software.u-net.com/applets/GridBagDemo/GridBagTest.htm

El administrador GridBagLayout acta un poco ms como GridLayout si usas las clases GridBagConstraints y utilizas los campos gridx y gridy para asignar una posicin en una cuadrcula "virtual" para cada componente que agregues. El applet demuestra esta posibilidad. Esto todava es un poco torpe y muy parecido a los otros administradores de disposicin. Las cosas empiezan a ponerse mucho ms interesante cuando empiezas a modificar otros campos de la clase GridBagConstraints para modificar la apariencia de los distintos componentes dentro de esta cuadrcula "virtual". Recuerda que aunque necesitas entender esto para los propsitos del examen, podra ser ms fcil que cuando ests programando en el mundo real una combinacin de controles de contenedores con otros administradores de disposicin. Un ejemplo de cuando esto no es una buena opcin es cuando necesita redimensionar dinmicamente componentes. sta es una situacin en donde herramientas de desarrollo como Visual Cafe o JBuilder no son de mucha ayuda y una buena comprensin del GridBagLayout puede ser esencial. He creado un applet de demostracin: http://www.software.u-net.com/applets/GridBagDemo/GridBagDynamic.htm que muestran el efecto de cambiar los parmetros de relleno dinmicamente para un solo botn en un grupo de botones desplegados con GridbagLayout Los campos de la clase GridBagConstraints son:

gridx gridy gridwidth y gridheight fill ipadx e ipady insets anchor weightx y weighty

Hojeando el excelente libro de Bill Brogdens Java2 Exam Cram, encontr una demostracin comprensiva del GridBagLayout en: http://www.austria.eu.net/java/programs/applets/missgable/index.htm

174

javaHispano. Tu comunidad, tu lenguaje.

Usando gridx y gridy para sugerir la posicin de un componente


Para este ejemplo supondremos que estas escribiendo el cdigo necesario para disear el programa de una agenda. Mostrars la hora de la cita abajo a la izquierda y los detalles de la cita abajo a la derecha. Las unidades de tiempo sern de media hora. Debido que una cita puede cubrir ms de una unidad de tiempo; por ejemplo puede durar una hora y media, necesitaras poder cambiar la altura de los detalles de la cita dinmicamente para cubrir ms de una unidad de tiempo. Debido a este requerimiento, de tener una altura variante para los detalles de las citas, utilizar GridLayout no es muy conveniente. Estars poniendo paneles en el Frame como contenedores. El primer paso es asegurarse que cada panel este lado a lado en el Frame principal de la Aplicacin.
import java.awt.*; import java.awt.event.*; public class GBCal extends Frame{ Panel pTimes=new Panel(); Panel pAps=new Panel(); TextField txTimes=new TextField("09.00"); TextField txAps=new TextField("Meet the boss"); GridBagLayout gbl=new GridBagLayout(); GridBagConstraints gbc=new GridBagConstraints(); public static void main(String argv[]){ GBCal gbc=new GBCal(); gbc.setLayout(new FlowLayout()); } public GBCal() { pTimes.add(txTimes); pAps.add(txAps); setLayout(gbl); gbc.gridx=0; gbc.gridy=0; pTimes.setBackground(Color.pink); add(pTimes,gbc); gbc.gridx=1; gbc.gridy=0; pAps.setBackground(Color.lightGray); add(pAps,gbc); setSize(300,300); setVisible(true); } }

175

Tutorial para el examen de certificacin: SCJP 1.2 Observa cmo las clases GridBagLayout y GridBagConstraints trabajan juntas. La instancia de GridBagConstraints gbc se reutiliza cada vez que se agrega un componente. En ningn punto especificas el nmero de filas y columnas para la cuadrcula, puesto que la clase GridBagLayout lo deduce de los campos gridx y gridy de la instancia de la clase GridBagConstraints.

Este es el resultado:

ipadx y ipady para controlar el relleno interior de los componentes


El cdigo ha puesto un color del fondo distinto para que puedas ver la magnitud de cada panel en lugar de ver simplemente la anchura de los campos de texto. Esto est bien, pero pensemos que ahora quieres que los campos de texto se estiren y abarquen de izquierda a derecha todo el Frame de la aplicacin principal. Esto se puede realizar modificando el campo ipadx de la clase GridBagConstraints. Esto puede ejecutarse poniendo:
gbc.ipadx=30; para las horas y gbc.ipadx=100; para los detalles

El cdigo queda:
import java.awt.*; import java.awt.event.*;

176

javaHispano. Tu comunidad, tu lenguaje.


public class GBCal extends Frame{ Panel pTimes=new Panel(); Panel pAps=new Panel(); TextField txTimes=new TextField("09.00"); TextField txAps=new TextField("Meet the boss"); GridBagLayout gbl=new GridBagLayout(); GridBagConstraints gbc=new GridBagConstraints(); public static void main(String argv[]){ GBCal gbc=new GBCal(); gbc.setLayout(new FlowLayout()); } public GBCal() { pTimes.add(txTimes); pAps.add(txAps); setLayout(gbl); gbc.gridx=0; gbc.gridy=0; gbc.ipadx=30; pTimes.setBackground(Color.pink); add(pTimes,gbc); gbc.gridx=1; gbc.gridy=0; gbc.ipadx=100; pAps.setBackground(Color.lightGray); add(pAps,gbc); setSize(300,300); setVisible(true); } }

y este es el resultado:

177

Tutorial para el examen de certificacin: SCJP 1.2

Componentes dentro de un panel utilizando GridBagLayout


Para el prximo paso quiero proporcionar a cada panel su propio administrador de disposicin GridBagLayout y agregar hendiduras para unidades de tiempo adicionales. Para propsitos de este ejemplo agregar solo una hendidura de tiempo mas y simplemente estirar el cuadro de texto del detalle de la cita para cubrir las hendiduras de las unidades de tiempo entre las 9.00 y 9.30. Para hacer esto crear una nueva instancia de la clase GridBagLayout llamada gbBut y la usare para preparar la cuadrcula para el panel pTimes para colocar las hendiduras de las unidades de tiempo una encima de otra verticalmente. El cdigo para realizar lo anterior es el siguiente:
//Controlar el panel de los tiempos con GridBagLayout pTimes.setLayout(gbBut); gbc.gridx=0; gbc.gridy=0; pTimes.add(txTimes9,gbc); gbc.gridx=0; gbc.gridy=1; pTimes.add(txTimes930,gbc);

Y este es el cdigo completo:


import java.awt.*; import java.awt.event.*; public class GBCal extends Frame{ Panel pTimes=new Panel(); Panel pAps=new Panel(); TextField txTimes9=new TextField("09.00"); TextField txTimes930=new TextField("09.30"); TextField txAps=new TextField("Meet the boss"); GridBagLayout gbl=new GridBagLayout(); GridBagLayout gbBut=new GridBagLayout(); GridBagConstraints gbc=new GridBagConstraints(); public static void main(String argv[]){ GBCal gbc=new GBCal(); gbc.setLayout(new FlowLayout()); } public GBCal() { setLayout(gbl); //Controlar el panel de tiempo con //GridBagLayout pTimes.setLayout(gbBut);

178

javaHispano. Tu comunidad, tu lenguaje.


gbc.gridx=0; gbc.gridy=0; pTimes.add(txTimes9,gbc); gbc.gridx=0; gbc.gridy=1; pTimes.add(txTimes930,gbc); pTimes.setBackground(Color.pink); //Reutilizamos gbc para la disposicin del panel principal gbc.gridx=0; gbc.gridy=0; gbc.ipadx=30; add(pTimes,gbc); pAps.setLayout(gbBut); gbc.gridx=0; gbc.gridy=1; pAps.add(txAps,gbc); gbc.gridx=1; gbc.gridy=0; gbc.ipadx=100; pAps.setBackground(Color.lightGray); add(pAps,gbc); setSize(300,300); setVisible(true); } }// fin de la clase

El resultado es el siguiente:

Esto esta trabajando bien hasta cierto punto. Tenemos ahora dos hendiduras para las unidades de tiempo, pero desafortunadamente el espacio para el detalle de la cita tiene 179

Tutorial para el examen de certificacin: SCJP 1.2 como valor predefinido el centro del campo de las citas y obtenemos una fila gruesa. Lo que quiero ahora es fijarla hasta arriba y estirarla para que cubra las dos hendiduras de tiempo.

Fijando componentes dentro de la cuadrcula


Si un componente no-llena el rea completa, puedes especificar en que parte del rea lo quieres usando el campo anchor de la clase GridBagConstraints. Los posibles valores son:
GridBagconstraints.CENTER GridBagconstraints.NORTH GridBagconstraints.NORTHEAST GridBagconstraints.EAST GridBagconstraints.SOUTHEAST GridBagconstraints.SOUTH GridBagconstraints.SOUTHWEST GridBagconstraints.WEST GridBagconstraints.NORTHWEST

En este caso quiero posicionar los campos en la parte superior (North) de los paneles que los contienen. He aumentado el espesor del campo del detalle de la cita aumentando el valor de ipady para la direccin del campo. Aqu esta el cdigo:
import java.awt.*; import java.awt.event.*; public class GBCal extends Frame{ Panel pTimes=new Panel(); Panel pAps=new Panel(); TextField txTimes9=new TextField("09.00"); TextField txTimes930=new TextField("09.30"); TextField txAps=new TextField("Meet the boss"); GridBagLayout gbl=new GridBagLayout(); GridBagLayout gbBut=new GridBagLayout(); GridBagConstraints gbc=new GridBagConstraints(); public static void main(String argv[]){ GBCal gbc=new GBCal(); gbc.setLayout(new FlowLayout()); } public GBCal() { setLayout(gbl); //Controlamos el panel de tiempos con GridBagLayout pTimes.setLayout(gbBut);

180

javaHispano. Tu comunidad, tu lenguaje.


//Aseguramos que los components se coloques //en la parte superior gbc.anchor=GridBagConstraints.NORTH; gbc.gridx=0; gbc.gridy=0; pTimes.add(txTimes9,gbc); gbc.gridx=0; gbc.gridy=1; pTimes.add(txTimes930,gbc); pTimes.setBackground(Color.pink); //Reutilizamos gbc para el panel principal gbc.gridx=0; gbc.gridy=0; gbc.ipadx=30; add(pTimes,gbc); pAps.setLayout(gbBut); gbc.gridx=0; gbc.gridy=1; gbc.ipady=12; pAps.add(txAps,gbc); gbc.gridx=1; gbc.gridy=0; gbc.ipadx=100; pAps.setBackground(Color.lightGray); add(pAps,gbc); setSize(300,300); setVisible(true); } }//fin de la clase

Y este es el resultado:

181

Tutorial para el examen de certificacin: SCJP 1.2

Elementos GridBag no cubiertos por este ejercicio


Este ejercicio ha cubierto los siguientes campos de la clase GridBagConstraints :

ipadx/y gridx/y anchor

La clase GridBagConstraints tiene los siguiente campos importantes:


weightx/y fill gridwidth/height insets

Los campos weightx/y controlan cmo un rea crece o se contrae ms all de su tamao inicial. As que si pones el campo weighty a cero el campo seguir manteniendo su altura constante aun cuando redimensiones la ventana. El campo fill controla cmo un componente se estira para llenar el rea. Al igual que el campo anchor puedes definir los valores del campo fill usando constantes ya definidas de la clase GridBagConstraints. stas son:
GridBagConstraints.NONE GridBagConstraints.HORIZONTAL GridBagConstraints.VERTICAL GridBagConstraints.BOTH

Los campos del gridwidth/height determinan cuntas columnas y filas tendr un componente. El campo insets indica el relleno "externo" que tendr a lo largo de los lmites de la celda de la cuadrcula.

182

javaHispano. Tu comunidad, tu lenguaje.

Preguntas Pregunta 1) Cul ser la apariencia de un applet con el cdigo siguiente?


import java.awt.*; public class FlowAp extends Frame{ public static void main(String argv[]){ FlowAp fa=new FlowAp(); fa.setSize(400,300); fa.setVisible(true); } FlowAp(){ add(new Button("One")); add(new Button("Two")); add(new Button("Three")); add(new Button("Four")); }//fin del constructor }//fin de la Application

1)Un Frame con botones etiquetados con "One", "Two", "Three","Four" colocados encada esquina 2)Un Frame con botones etiquetados con "One", "Two", "Three","Four" colocados de arriba hacia abajo 3)Un Frame con un botn grande etiquetado con "Four" en el Centro 4)Se generar un error al momento de la ejecucin indicando que no has puesto un
LayoutManager

Pregunta 2) Cmo indicas dnde se posicionar un componente utilizando Flowlayout? 1)Utilizando las constantes North, South, East, West 2)Asignando una referencia fila/columna 3)Pasando un porcentaje X/Y como parmetro al mtodo add 4)No es necesario indicarlo, el administrador FlowLayout posicionar el componente

183

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 3) Cmo le haces para cambiar al administrador de disposicin actual a un contenedor? 1)Usando el mtodo setLayout 2)Una vez creado no puedes cambiar el administrador de disposicin de un componente 3)Usando el mtodo setLayoutManager 4)Usando el mtodo updateLayout

Pregunta 4) Qu pasa si agregas una Scrollbar en la parte Norte de un Frame? 1)El Frame se agrandar para permitir que el Scrollbar ocupe su tamao predefinido. 2)El Scrollbar se colocar en la parte Norte del Frame, ser muy ancho, muy grueso y no muy til 3)No puedes agregar un Scrollbar en la parte Norte de un Frame, slo al Este o al Oeste 4)El Scrollbar se estirar desde arriba hasta abajo del Frame

Pregunta 5) Qu pasa si agregas ms botones de los que definiste en un GridLayout y las etiquetas de cada botn son demasiado largas? 1)El tamao del contenedor se aumentara para permitir que las etiquetas de cada botn se desplieguen completamente 2)El GridLayout ignorar el largo de cada etiqueta y stas se truncarn 3)Se generar un error al compilar indicando que los botones no pueden alcanza su tamao predefinido 4)Se generar un error al ejecutarse indicando que los botones no puede alcanzar su tamao predefinido

Pregunta 6) Cuales de las siguientes declaraciones son verdaderas?

184

javaHispano. Tu comunidad, tu lenguaje. 1)Puedes controlar la posicin un componente llamando al mtodo setLayout(new
GridBagConstraints ())

2)El administrador de disposicin FlowLayout puede ser usado para controlar la posicin de componentes utilizando GridBagLayout 3)El administrador de disposicin GridBagLayout toma las constantes North,
South, East, West y Center

4)Ninguna de estas respuestas es verdadera

Pregunta 7) Cuales de los siguiente son campos de la clase de GridBagConstraints? 1) ipadx 2) fill 3) insets 4) width

Pregunta 8) Cual ser la apariencia mas probable del siguiente cdigo despus de ejecutarse?
import java.awt.*; public class CompLay extends Frame{ public static void main(String argv[]){ CompLay cl = new CompLay(); } CompLay(){ Panel p = new Panel(); p.setBackground(Color.pink); p.add(new Button("One")); p.add(new Button("Two")); p.add(new Button("Three")); add("South",p); setLayout(new FlowLayout()); setSize(300,300); setVisible(true); } }

1)Los botones se colocarn de izquierda a derecha a lo largo de la parte inferior del


Frame

2)Los botones se colocarn de izquierda a derecha a lo largo de la parte superior del


Frame

3)Los botones no se desplegarn 185

Tutorial para el examen de certificacin: SCJP 1.2 4)Solo se mostrarn los tres botones ocupando todo el Frame

Pregunta 9) Cules de estas declaraciones son ciertas respecto al campo anchor? 1)Es un campo del administrador de disposicin GridBagLayout para controlar la colocacin de componentes 2)Es un campo de la clase GridBagConstraints para controlar la colocacin de componentes 3)Una constante valida para el campo anchor es GridBagConstraints.NORTH 4)El campo anchor controla la altura de los componentes agregados a un contenedor

Pregunta 10) Al usar el administrador de disposicin GridBagLayout, cada nuevo componente agregado requiere una nueva instancia de la clase GridBagConstraints. Es esto : 1)Verdadero 2)Falso

Respuestas Respuesta 1 3)Un Frame con un botn grande etiquetado con "Four" en el Centro Si no especificas una constante, cualquier componente agregado a un contenedor que utilice el administrador de disposicin BorderLayout se colocar en el centro. El administrador de disposicin de un Frame por omisin es BorderLayout. Respuesta 2 4)No es necesario indicarlo, el administrador FlowLayout posicionar el componente Respuesta 3 1)Usando el mtodo setLayout Respuesta 4

186

javaHispano. Tu comunidad, tu lenguaje. 2)El Scrollbar se colocar en la parte Norte del Frame, ser muy ancho, muy grueso y no muy til Respuesta 5 2)El GridLayout ignorar el largo de cada etiqueta y stas se truncarn Respuesta 6 4)Ninguna de estas respuestas es verdadera Respuesta 7 1) ipadx 2) fill 3) insets Respuesta 8 2)Los botones se colocarn de izquierda a derecha a lo largo de la parte superior del
Frame

Cuando un administrador de disposicin se cambia a FlowLayout el BorderLayout predefinido no se aplica y el panel se coloca en la parte superior del Frame. Respuesta 9 2)Es un campo de la clase GridBagConstraints para controlar la colocacin de componentes 3)Una constante valida para el campo anchor es GridBagConstraints.NORTH Respuesta 10 2)Falso

Otras Fuentes para este tema: Este tema es cubierto por el tutorial de sun en: http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html Richard Baldwin cubre este tema en: BorderLayout http://www.geocities.com/Athens/7077/Java114.htm FlowLayout http://www.geocities.com/Athens/7077/Java116.htm GridLayout

187

Tutorial para el examen de certificacin: SCJP 1.2


http://www.geocities.com/Athens/7077/Java118.htm Richard parece no cubrir el GridBagLayout Jan Newmarsh en Australia a creado esta pagina http://pandonia.canberra.edu.au/java/xadvisor/gridbag/gridbag.html Jyothi Krishnan en http://www.geocities.com/SiliconValley/Network/3693/obj_sec8.html#obj25

188

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2.
Escribir cdigo que implemente clases oyentes (Listener) y en mtodos oyentes extraer informacin del evento para determinar el componente afectado ya sea para conocer la posicin actual del ratn o el nmero de veces que se llama a un evento. Determinar el nombre de clase de un evento para cualquier interface oyente especificada en el paquete
java.awt.event.

El modelo oyente -Listener- de eventos


Para escribir cualquier aplicacin til con interfaz grfica de usuario (GUI) utilizando Java necesitas entender el funcionamiento las clases oyentes y la manera de extraer informacin de los eventos que ellas procesan. El sistema de manejo o gestin de eventos en Java cambi significativamente entre las versiones 1.0x y 1.1. En la versin 1.0x el cdigo para manejar eventos se pareca bastante al cdigo C llano para Windows, es decir bastante horrible. Requera la creacin de grandes sentencias case donde colocabas el cdigo para procesar un evento en particular de acuerdo con los parmetros pasados. Este sistema es bastante sencillo de entender para ejemplos triviales pero no es recomendable para programas ms grandes. Tengo la impresin de que lo ms relevante que necesita saber para el examen es que la gestin de eventos de la versin 1.1 no es compatible con versiones anteriores. En teora, el cdigo escrito con el estilo de cdigo de la versin 1.0x para el manejo de eventos debe trabajar bien en versiones posteriores del JDK.

El modelo de eventos del JDK 1.1.


El sistema de gestin de eventos de Java 1.1 involucra el uso de clases oyentes -Listenerque son eficazmente "ligadas" a los componentes para procesar eventos especficos. Esto favorece a las herramientas de desarrollo de aplicaciones GUI para que generen automticamente cdigo que maneje los eventos. Si examinas el cdigo generado por una de estas herramientas puede que te parezca confuso, esto es en parte debido a que tienden a involucrar clases internas creadas dentro de los mtodos. Con el propsito de aprenderlo puedes manejar las clases de gestin de eventos como si fueran clases de alto nivel. Uno de los factores complicados para la gestin de eventos es que sta se basa en Interfaces, pero es mucho ms fcil de usar utilizando una serie de clases conocidas como las clases Adaptadoras -Adapter- , qu simplemente implementan las interfaces del evento. Cuando usas una interface necesitas implementar todos sus mtodos, as el uso directo de la interface EventListener requiere la creacin de mtodos con cuerpos

NT. El modelo de la versin 1.1 se conoce en algunos documentos como gestin de eventos delegados.

189

Tutorial para el examen de certificacin: SCJP 1.2 vacos para cualquier evento de la interface que no se utilice. Usando las clases Adaptadoras slo necesitas crear los cuerpos de los mtodos de los eventos que realmente utilizas.

Las clases Adaptadoras -Adapter- te permiten usar las Interfaces oyentes sin tener que crear un cuerpo para cada uno de los mtodo de la interface.

Uno de los eventos esenciales ms manejados para una aplicacin sencilla es la habilidad de cerrar la aplicacin como respuesta a seleccionar la opcin cerrar proporcionada por el sistema operativo. Te puede sorprender que el manejo de este evento no venga ya implementado por omisin en un Frame. Si crea una aplicacin que herede un Frame, pero no creas cdigo para cerrarlo, tendrs qu o bien terminar el proceso desde el gestor de tareas o, en Windows, ir a la lnea de comandos y pulsar CTRL-C. El equivalente Swing del componente Frame es el JFrame, el JFrame procesa su cierre como una accin predefinida, pero la certificacin no cubre los componentes Swing. El funcionamiento del Frame de AWT es un buen lugar para comenzar a cubrir el tema de gestin de eventos. Los mtodos para manejar los eventos de las ventanas (WindowEvent) no son tan intuitivos como los mtodos de otros eventos. As al principio no es obvio a cual de los mtodos siguientes necesitas responder para cerrar el Frame:
windowClosed o windowClosing

De hecho es el mtodo windowClosing el que necesita ser procesado. La manera ms simple de destruir la ventana es usando la lnea:
System.exit(0);

Aqu un ejemplo de una aplicacin sencilla que muestra un Frame que responder desaparecindose cuando se accione la opcin cerrar proporcionada por el sistema operativo:
import import public public java.awt.event.*; // necesario para el manejo de eventos java.awt.*; class ShutHello extends Frame{ static void main(String argv[]){ ShutHello h = new ShutHello();

} ShutHello(){

NT: en Windows es la x que aparece en la esquina superior derecha o la pulsacin de las teclas ALT-F4

190

javaHispano. Tu comunidad, tu lenguaje.


Button b = new Button("ShutHello"); //creamos una instancia de la clase WindowCloser WindowCloser wc = new WindowCloser(); //Ligamos el oyente con el programa addWindowListener(wc); this.add(b); setSize(300,300); setVisible(true);

} } class WindowCloser extends WindowAdapter{ //sobreescribimos uno de los metodos del Adaptador public void windowClosing(WindowEvent e){ System.exit(0); } }

La segundo mitad del objetivo pide que conozcas el nombre de clase por cada evento de cada interface oyente. La tabla que aparece mas adelante lista todas las interfaces oyentes junto con sus mtodos. As la interface MouseListener ofrece mtodos para los eventos:

clicked pressed released entered exited

Si comparas estos con los eventos manejados en Visual Basic 5 la nica rea significante que no se cubre es un conjunto de mtodos para manejar los eventos de arrastre con el ratn(Drag&Drop) El nombre de la clase del Evento pasado a cada mtodo es bastante intuitivo y basado en el nombre de la clase Oyente. As todos los mtodos de ActionListener toman un parmetro de tipo ActionEvent, los mtodos de ComponentListener toman un tipo de ComponentEvent, un ContainerListener toma un ComponentEvent, etc, etc, etc. Existen 11 interfaces oyentes en total, pero slo 7 de ellas tienen mltiples mtodos. Como lo relevante de los adaptadores es eliminar la necesidad de implementar mtodos en blanco, slo se implementan las clases Adaptadoras para estas 7 Interfaces stas son las siguientes:
ContainerAdapter

191

Tutorial para el examen de certificacin: SCJP 1.2


FocusAdapter KeyAdapter MouseAdapter MouseMotionAdapter WindowAdapter

La siguiente tabla muestra la lista completa de interfaces para gestionar eventos.

Interfaces para la gestin de eventos ActionListener AdjustmentListener ComponentListener actionPerformed(ActionEvent) addActionListener() addComponentListener() adjustmentValueChanged(AdjustmentEvent) addAdjustmentListener()

componentHidden(ComponentEvent) componentMoved(ComponentEvent) componentResized(ComponentEvent) componentShown(ComponentEvent) ContainerListener componentAdded(ContainerEvent) componetRemoved(ContainerEvent) FocusListener focusGained(FocusEvent) focusLost(FocusEvent) ItemListener itemStateChanged(ItemEvent) KeyListener keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) MouseListener mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) MouseMotionListener mouseDragged(MouseEvent) mouseMoved(MouseEvent) TextListener textValueChanged(TextEvent) WindowListener windowActivated(WindowEvent) windowClosed(WindowEvent) windowClosing(WindowEvent) windowDeactivated(WindowEvent) windowDeiconified(WindowEvent) windowIconified(WindowEvent) |windowOpened(WindowEvent)

addContainerListener() addFocusListener() addItemListener() addKeyListener()

addMouseListener()

addMouseMotionListener() addTextListener() addWindowListener()

192

javaHispano. Tu comunidad, tu lenguaje.

Preguntas Pregunta 1) Cules de las siguientes afirmaciones son ciertas? 1)Para un componente dado sus eventos se procesar en el orden en que los oyentes fueron agregados. 2)Usar las clases Adaptadoras para el manejo de eventos significa crear cuerpos vacos para todos los mtodos que no se utilicen. 3)Un componente puede tener mltiples oyentes asociados a l 4)Pueden quitarse oyentes una vez agregados.

Pregunta 2) Cules de las siguientes lneas son mtodos validos para el manejo de eventos?
1) 2) 3) 4) mousePressed(MouseEvent e){} MousePressed(MouseClick e){} functionKey(KeyPress k){} componentAdded(ContainerEvent e){}

Pregunta 3) Que pasara cuando intentes compilar y ejecutar el siguiente cdigo?


import java.awt.*; import java.awt.event.*; public class MClick extends Frame implements MouseListener{ public static void main(String argv[]){ MClick s = new MClick(); } MClick(){ this.addMouseListener(this); } public void mouseClicked(MouseEvent e){ System.out.println(e.getWhen()); } }

1)Se generar un error al compilar.

193

Tutorial para el examen de certificacin: SCJP 1.2 2)Se generar un error al ejecutarse. 3)Se compilar y durante su ejecucin mostrara la fecha y la hora por cada click 3)Se compilar y durante su ejecucin la hora por cada click Pregunta 4) Cules de las siguientes afirmaciones, respecto al manejo de eventos, son verdaderas? 1) El modelo de Eventos de la versin 1.1 es totalmente compatible con modelo de evento de la versin 1.0 2)El cdigo escrito para el manejo de eventos en la versin 1.0x se ejecutar sin problemas sobre la versin 1.1 de la JVM. 3)El modelo de Eventos de la versin 1.1 est particularmente ajustado a las herramientas para la construccin de aplicaciones GUI. 4) El manejo del evento DragDrop fue agregado con la versin 1.1 del modelo de manejo de eventos.

Respuestas Respuesta 1) 3)Un componente puede tener mltiples oyentes asociados a l 4)Pueden quitarse oyentes una vez agregados. Respuesta 2)
1)mousePressed(MouseEvent e){} 4)componentAdded(ContainerEvent e){}

Respuesta 3) 1)Se generar un error al compilar. Debido a que este cdigo utiliza una interface oyente de eventos, se deben crear cuerpos vacos para cada uno de los mtodos de la interface. Este cdigo causar errores que advierten que MClick es una clase abstracta. Respuesta 4) 2)El cdigo escrito para el manejo de eventos en la versin 1.0x se ejecutar sin problemas sobre la versin 1.1 de la JVM. 3)El modelo de Eventos de la versin 1.1 est particularmente ajustado a las herramientas para la construccin de aplicaciones GUI.

194

javaHispano. Tu comunidad, tu lenguaje. El cdigo para el modelo de manejo de eventos de la versin 1.1 no funcionara con la versin 1.0x de la JVM. El mtodo DragDrop no existe, yo lo invente.

Otras Fuentes sobre este tema: Tutorial de Sun http://java.sun.com/docs/books/tutorial/uiswing/events/intro.html Richard Baldwin http://www.Geocities.com/Athens/7077/Java080.htm#design goals of the jdk 1.1 delegation Jyothi Krishnan http://www.geocities.com/SiliconValley/Network/3693/obj_sec8.html#obj25 David Reilly http://www.davidreilly.com/jcb/java107/java107.html

195

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 9. El paquete java.lang.Math


Objetivo 1.
Escribir cdigo que utilice los siguientes mtodos de la clase java.lang.Math: abs,
ceil, floor, max, min, random, round, sin, cos, tan y sqrt.

Nota sobre este objetivo


La clase java.lang.Math tiene el modificador final, por consiguiente sus mtodos son estticos. Esto significa que no puedes heredar la clase para crear o modificar las versiones de estos mtodos. Esto es probablemente favorable ya que reduce la posibilidad de ambigedad. Con certeza encontraras preguntas sobre estos mtodos y sera una verdadera pena que no las contestes correctamente simplemente porque los pasaste por alto.

abs
Hasta que comenc ha estudiar para el examen de certificacin no tena ni idea de lo que hace el mtodo abs. Elimina el signo de un nmero y retorna el numero simplemente. As la siguiente lnea de cdigo mostrar simplemente 99. Si el nmero es positivo obtendrs como resultado el mismo nmero.
System.out.println(Math.abs(-99));

ceil
Este mtodo retorna el prximo nmero entero hacia arriba. Si tienes lo siguiente:
ceil(1.1)

El resultado sea 2.0. Si cambias lo anterior por:


ceil(-1.1)

el resultado ser -1

196

javaHispano. Tu comunidad, tu lenguaje.

floor
De acuerdo a la documentacin del JDK este mtodo devuelve: El valor double ms grande que no sea mayor que el argumento pasado y que sea igual a un entero. Si tienes aun dudas de lo que significa lo anterior, aqu hay un pequeo programa y sus resultados:
public class MyMat{ public static void main(String[] argv){ System.out.println(Math.floor(-99.1)); System.out.println(Math.floor(-99)); System.out.println(Math.floor(99)); System.out.println(Math.floor(-.01)); System.out.println(Math.floor(0.1)); } }

los resultados son:


-100.0 -99.0 99.0 -1.0 0.0

max y min
Toma nota de lo siguiente: los siguientes dos mtodos toman dos parmetros. Puedes encontrar preguntas con ejemplos incorrectos que les pasan slo un parmetro. Como podras esperar estos mtodos son el equivalente de decir: "Cual es ms grande: ESTE parmetro o ESTE parmetro" El siguiente cdigo muestra como funcionan estos mtodos:
public class MaxMin{ public static void main(String argv[]){ System.out.println(Math.max(-1,-10)); System.out.println(Math.max(1,2)); System.out.println(Math.min(1,1)); System.out.println(Math.min(-1,-10)); System.out.println(Math.min(1,2)); } }

197

Tutorial para el examen de certificacin: SCJP 1.2

Estos son los resultados:


-1

2 1 -10 1

random
Retorna un nmero aleatorio entre 0.0 y 1.0 (0.0 <=n<1) A diferencia de algunos sistemas que generan nmeros aleatorios Java no parece ofrecer la funcionalidad de pasar un nmero como semilla para aumentar la aleatoriedad. Para propsitos del examen uno de los aspectos importantes a considerar de este mtodo es que el valor de retorno est entre 0.0 y 1.0. As los resultados de una tpica secuencia de ejecuciones podran ser: 0.9151633320773057 0.25135231957619386 0.10070205341831895 A menudo un programa necesita producir un nmero aleatorio entre 0 y 10 o 0 y 100. El cdigo siguiente combina cdigo matemtico para producir un nmero aleatorio entre 0 y 100.
System.out.println(Math.round(Math.random()*100));

round
Redondea al entero ms cercano. Para qu, si el valor tiende ms de la mitad hacia el entero ms alto, el valor es redondeado al entero siguiente. En caso contrario el valor retornado es el entero anterior. Si por ejemplo el valor a redondear es x entonces: 2.0 <=x < 2.5. entonces Math.round(x)==2.0 2.5 <=x < 3.0 entonces Math.round(x)==3.0 Aqu hay otros ejemplo con sus resultados:
System.out.println(Math.round(1.01)); System.out.println(Math.round(-2.1)); System.out.println(Math.round(20));

198

javaHispano. Tu comunidad, tu lenguaje.

1 -2 20

sin cos tan


Estos mtodos elegantes toman un parmetro de tipo double y hacen justo las mismas funciones elegantes que realizaran en cualquier otro lenguaje que hayas usado. En mi caso, que son 12 aos de programacin, nunca he usado una de estas funciones. As quizs lo nico que debemos recordar es que el parmetro que recibe es de tipo double.

sqrt
Retorna un valor tipo double que es la raz cuadrada del valor pasado como parmetro.

Resumen
Los mtodos max y min toman dos parmetros El mtodo random retorna un valor entre 0 y 1 El mtodo abs elimina el signo del valor pasado como parmetro El mtodo round redondea un numero eliminando as la parte que esta despus del punto decimal, pero conserva el signo del nmero.

Pregunta 1) Cuales de las siguientes lneas se compilarn correctamente?


1) 2) 3) 4) System.out.println(Math.max(x)); System.out.println(Math.random(10,3)); System.out.println(Math.round(20)); System.out.println(Math.sqrt(10));

199

Tutorial para el examen de certificacin: SCJP 1.2

Pregunta 2) Cul de las siguientes lneas mostrara un valor aleatorio con valor entre 1 y10?
1) 2) 3) 4) System.out.println(Math.round(Math.random()* 10)); System.out.println(Math.round(Math.random() % 10)); System.out.println(Math.random() *10); Ninguna de las anteriores

Pregunta 3) Cul ser la salida de la siguiente lnea?


System.out.println(Math.floor(-2.1));

1) -2 2) 2.0 3) -3 4) -3.0 Pregunta 4) Cul ser la salida de la siguiente lnea?


System.out.println(Math.abs(-2.1));

1) -2.0 2) -2.1 3) 2.1 4) 1.0

Pregunta 5) Cul ser la salida de la siguiente lnea?


System.out.println(Math.ceil(-2.1));

1) -2.0 2) -2.1

200

javaHispano. Tu comunidad, tu lenguaje. 3) 2.1 3) 1.0 Pregunta 6) Qu pasar cando intentes compilar y ejecutar el siguiente cdigo?
class MyCalc extends Math{ public int random(){ double iTemp; iTemp=super(); return super.round(iTemp); } } public class MyRand{ public static void main(String argv[]){ MyCalc m = new MyCals(); System.out.println(m.random()); } }

1)Se generar un error al compilarse 2)Se generar un error al ejecutarse 3)Se ejecutar y mostrara un valor aleatorio entre 0 y 1 4) Se ejecutar y mostrara un valor aleatorio entre 1 y 10

Respuestas Respuesta 1)
3) System.out.println(Math.round(20)); 4) System.out.println(Math.sqrt(10));

La opcin 1 es incorrecta porque el mtodo max recibe dos parmetros no uno, y la opcin 2 es incorrecta ya que el mtodo random recibe solo un parmetro no dos Respuesta 2) 4) Ninguna de las anteriores La opcin ms cercana a la correcta es la 1 pero el detalle esta en recordar que el mtodo random incluye el 0 y la pregunta pide valores entre 1 y 10.

201

Tutorial para el examen de certificacin: SCJP 1.2 Respuesta 3) 4) -3.0 Respuesta 4) 3) 2.1 Respuesta 5) 1) -2.0 Respuesta 6) 1)Se generar un error al compilarse La clase Math tiene el modificador final y por eso no puede ser heredada. Otras Fuentes para este tema Jyothi Krishnan en http://www.geocities.com/SiliconValley/Network/3693/obj_sec9.html#obj28

202

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 2
Nota sobre este objetivo
La teora de la inmutabilidad de la clase String dice que una vez creado, un String nunca puede modificarse. En nuestra experiencia programando con Java en la vida real nos damos cuenta que esto no es del todo cierto. Veamos el siguiente cdigo:
public class ImString{ public static void main(String argv[]){ String s1 = new String("Hello"); String s2 = new String("There"); System.out.println(s1); s1=s2; System.out.println(s1); } }

Si un String no puede cambiarse entonces s1 debera mostrar siempre "Hello" , pero si pruebas el cdigo te dars cuenta que en la segunda ejecucin del println se muestra la cadena "There". Entonces Que pasa? La inmutabilidad se refiere realmente a los puntos de referencia de los Strings. Cuando se asignan s2 a s1 en el ejemplo, el String que contiene "Hello" deja de ser referenciado y ahora s1 apunta a la misma referencia que s2. De hecho la cadena "Hola" realmente no se ha modificado es solo que tericamente ya no puedes "llegar a ella". El objetivo te pide que reconozcas las implicaciones de la inmutabilidad de las cadenas, y la principal parece ser qu si quieres eliminar y cambiar el contenido de cadenas de texto debes utilizar la clase StringBuffer que viene construida con ms mtodos para esos propsitos. Debido a que la concatenacin de Strings causa que un nuevo String sea instanciado "fuera de escena", puede haber un desempeo poco eficiente si ests manipulando grandes cantidades de Strings, como sucede al leer un archivo con gran cantidad de texto. Generalmente la inmutabilidad de la clase String no altera nuestra programacin diaria, pero se cuestionar en el examen. Recuerda que de cualquier manera que te hagan la pregunta, una vez creado un String no puede cambiarse an cuando la referencia a l se cambie para apuntar a algn otro String. Aunque ni los objetivos especficos del

203

Tutorial para el examen de certificacin: SCJP 1.2 examen para Java2 ni para Java 1.1 lo mencionan, estoy bastante seguro que algunas preguntas requieren conocimiento sobre la clase StringBuffer.

Preguntas Pregunta 1) Has creado dos Strings que contienen nombres. As:
String fname="John"; String lname="String"

Cmo puedes cambiar estos Strings para que tomen nuevos valores dentro del mismo bloque de cdigo?
1) fname="Fred"; lname="Jones"; 2) String fname=new String("Fred"); String lname=new String("Jones"); 3) StringBuffer fname=new StringBuffer(fname); StringBuffer lname=new StringBuffer(lname); 4) Ninguna de las anteriores

Pregunta 2) Ests creando un programa para leer en archivo del texto de 8 MB. Cada nueva lnea leda se agrega a un objeto String pero te ests dando cuenta que, tristemente, le falta desempeo. Cul es probablemente la explicacin?

204

javaHispano. Tu comunidad, tu lenguaje. 1)El sistema de Entrada/Salida(I/O) de Java se disea alrededor de un comn denominador de mas bajo nivel y es inherentemente lento 2)La clase String es inapropiada para operaciones de I/O, un arreglo de caracteres sera ms conveniente. 3)Debido a que los Strings son inmutables un nuevo String se crea con cada lnea leda, Cambindolo por un StringBuffer puedes aumentar el desempeo. 4)Ninguna de las anteriores.

Respuestas Respuesta 1)
4) Ninguna de las anteriores

Una vez creado un String slo se puede leer y no puede modificarse. Respuesta 2) 3)Debido a que los Strings son inmutables un nuevo String se crea con cada lnea leda, Cambindolo por un StringBuffer puedes aumentar el desempeo. Espero que ninguno de los programadores en C hayan sugerido un arreglo de caracteres.

Otras Fuentes para este tema: Este tema es cubierto en el tutorial de Sun en: http://java.sun.com/docs/books/tutorial/essential/strings/stringsAndJavac.html (no entra mucho en detalle) Jyothi Krishnan cubre este tema en: http://www.geocities.com/SiliconValley/Network/3693/obj_sec9.html#obj29

205

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 10. El paquete java.util


Objetivo 1.
Hacer una seleccin apropiada de las clases/interfaces de colecciones para satisfacer requisitos de comportamientos especficos

Nota sobre este objetivo


Aunque no lo menciona especficamente, este objetivo involucra uno de los nuevos objetivos para la versin del examen de Java 2, conocer las clases de colecciones. Lo que el examen cuestiona sobre estas nuevas clases es bastante bsico, pide un conocimiento sobre donde y cmo podras usarlas, en lugar de conocer detalladamente sus campos y mtodos.

Las colecciones antiguas


La API Java 2 incluye nuevas interfaces y clases para reforzar las colecciones ya disponibles. Las primeras versiones de Java incluyeron:
vector hashtable array BitSet

De stos, slo el array era incluido en los objetivos para el examen de certificacin de la versin 1.1. Una de las omisiones notables de Java 1.1 era el soporte para ordenar, un requisito muy comn en cualquier situacin de programacin.

Las nuevas colecciones


La raz de la API de colecciones es la interface Collection. Esta te proporciona una serie de mtodos comunes que tendrn todas las clases de colecciones. Probablemente nunca crearas tu propia clase para implementar la interface Collection ya que Java te proporciona una serie de subclases y clases que usan esta interface. Java 2 incluye las siguiente nuevas clases de colecciones:
Sets Maps

Y una nueva clase llamada Set.

206

javaHispano. Tu comunidad, tu lenguaje. Las clases que implementan la interface Collection ms que almacenar tipos de datos primitivos, almacenan objetos. Todo esto tiene inconvenientes ya que la creacin de objetos reduce el rendimiento y a los elementos antes de usarse se les aplica un cast, al tipo apropiado, para que puedan ser utilizarlos. Esto tambin significa que las colecciones no verifican que los elementos sean todos el mismo tipo, ya que un objeto puede ser casi cualquier cosa.

Set
Set es una interface de colecciones que no puede contener elementos duplicados. De esta

manera se presta para manejar conceptos como el de un conjunto de registros retornados de una base de datos relacional. Parte de la magia de la interface Set esta en el mtodo add.
add(Object o)

Cualquier objeto pasado al mtodo add puede implementar el mtodo equals para que el valor pueda compararse con objetos existentes en la clase. Si la clase ya contiene ste objeto la llamada al mtodo add no modifica el contenido y retorna false. La idea de retornar false cuando intentas agregar un elemento que ya existe se parece ms a la manera en que trabaja C/C++ que la manera en que trabaja Java. La mayora de los mtodos similares en Java lanzan una Excepcin en este tipo de situaciones.

List
List es una interface de colecciones ordenadas que puede contener elementos

duplicados. Algunos de sus mtodos ms importantes son:


add remove clear

La documentacin de JDK da como ejemplo usar List para manejar una GUI que controle una lista que contiene todos los nombres de los Planetas.

Map
Map es una interface, las clases que la implementen no pueden tener llaves duplicadas y es similar a Hashtables.

Por qu utilizar colecciones en lugar de arreglos? 207

Tutorial para el examen de certificacin: SCJP 1.2

La gran ventaja de las colecciones sobre los arreglos es que las colecciones son desarrollables , es decir, no tienes que asignarles un tamao al momento de crearlas. El inconveniente de las colecciones es que slo guardan objetos y no tipos primitivos e inevitablemente afectan el rendimiento de la aplicacin. Los arreglos no soportan directamente el ordenamiento, pero esto puede ser superado usando los mtodos estticos de las colecciones. Aqu hay un ejemplo:
import java.util.*; public class Sort{ public static void main(String argv[]){ Sort s = new Sort(); } Sort(){ String s[] = new String[4]; s[0]="z"; s[1]="b"; s[2]="c"; s[3]="a"; Arrays.sort(s); for(int i=0;i< s.length;i++) System.out.println(s[i]); } }

Las colecciones Set y Map aseguran la individualidad de sus elementos, List no asegura esta individualidad pero permite que sus elementos se ordenen.

Usando Vectores
El siguiente ejemplo muestra cmo puedes agregar objetos de diferentes clases a un Vector. Esto contrasta con los arreglos donde cada elemento debe ser del mismo tipo. El cdigo avanza por cada objeto mostrando su contenido. Al mostrarse el contenido, implcitamente se accede al mtodo toString() de cada objeto.
import java.awt.*; import java.util.*; public class Vec{ public static void main(String argv[]){ Vec v = new Vec(); v.amethod(); }//fin de main public void amethod(){

208

javaHispano. Tu comunidad, tu lenguaje.


Vector mv = new Vector(); //nota como un Vector puede almacenar //objetos de distintos tipos mv.addElement("Hello"); mv.addElement(Color.red); mv.addElement(new Integer(99)); //la siguiente linea causara un error //ya que un vector no almacena tipos primitivos //mv.addElement(99) //Ahora avanzamos por cada elemento del vector for(int i=0; i< mv.size(); i++){ System.out.println(mv.elementAt(i)); } }//fin de amethod

Antes de Java2 el uso de la clase del Vector era la manera principal de crear una estructura de datos re-dimensionable. Los elementos de esta clase pueden quitarse con el mtodo remove .

Usando Hashtables
Las Hashtables son parecidas al concepto en Visual Basic de una coleccin que usa una llave. Acta como un Vector, slo que en lugar de referirte a los elementos por un nmero, te refieres a ellos por una llave. La palabra hash de su nombre se refiere a un trmino matemtico que hace referencia al manejo de ndices. Una Hashtable puede ofrecer un beneficio superior sobre un Vector, su rapidez

BitSet
Un BitSet como su nombre lo indica, almacena una secuencia de bits. No te confundas por la parte "set" de su nombre, no es un conjunto matemtico o algo relacionado con bases de datos, tampoco se relaciona con los conjuntos(Sets) disponibles en Java2. Es ms apropiado pensar en l como un vector de bits. Un BitSet puede ser til para el almacenamiento eficaz de bits, en donde los bits se usen para representar los valores de true/false. La alternativa de usar alguna clase de colecciones que contenga valores tipo Boolean puede ser menos eficaz. Segn Bruce Eckel en Thinking in Java Slo es eficaz desde el punto de vista del tamao; si ests buscando un acceso eficaz, es ligeramente ms lento que el uso de un arreglo de algn tipo primitivo.

209

Tutorial para el examen de certificacin: SCJP 1.2 Un BitSet es un poco una clase novedosa de la que nunca puedes llegar a necesitar. Sospecho que podra ser conveniente para propsitos criptogrficos o para el procesamiento de imgenes. Por favor avsame si te encuentras con alguna pregunta relacionada con esta clase en el examen.

Pregunta 1) Cules de las siguientes clases son colecciones? 1) Collection 2) Iterator 3) HashSet 4) Vector

Pregunta 2) Cules de los siguientes enunciados son verdaderos respecto a la interface Collection? 1)La clase Vector a sido modificada para implementar la interface Collection 2)La interface Collection ofrece mtodos individuales y mtodos colectivos como
addAll

3)La interface Collection es compatible con versiones anteriores y todos sus mtodos estn disponibles dentro de las clases del JDK 1.1. 4)Las clases de colecciones hacen innecesario el uso de arreglos.

Pregunta 3) Cules de las siguientes declaraciones son verdaderas? 1)La interface Set se diseo para asegurar que la implementacin de clases tengan miembros nicos 2)Las clases que implementan la interface List no pueden contener elementos duplicados

210

javaHispano. Tu comunidad, tu lenguaje. 3) la interface Set se diseo para almacenar registros retornados de una consulta a una base de datos 4) la Interface Map no es parte del marco de trabajo de las colecciones

Pregunta 4) Cules de las siguientes declaraciones son verdaderas? 1) los elementos de clase de colecciones pueden ser ordenados usando el mtodo sort de la interface Collection 2)Puedes crear una coleccin ordenada instanciando una clase que implemente la interface List 3)El mtodo sort de la interface Collection toma como parmetros una A o una D para indicar el orden, Ascendente/Descendente 4)Los elementos de una clase de colecciones pueden ser ordenados usando el mtodo order de la interface Collection

Pregunta 5) Deseas almacenar una cantidad pequea de datos y hacerlos disponibles para un acceso rpido. No necesitaras que los datos sean ordenados, la singularidad no es un problema y los datos permanecern bastante estticos Qu estructura de datos podra ser la mas conveniente para este requisito? 1)TreeSet 2)HashMap 3)LinkedList 4)Un arreglo

Pregunta 6) Cuales de las siguientes son clases Collection? 1) ListBag 2) HashMap 3) Vector 4) SetList

211

Tutorial para el examen de certificacin: SCJP 1.2 Pregunta 7) Cmo puedes remover un elemento de un Vector? 1)Con el Mtodo delete 2)Con el Mtodo cancel 3)Con el Mtodo clear 4)Con el Mtodo remove

Respuestas Respuesta 1) 3) HashSet 4) Vector Las otras 2 son interfaces. Respuesta 2) 1)La clase Vector a sido modificada para implementar la interface Collection 2)La interface Collection ofrece mtodos individuales y mtodos colectivos como
addAll

Las clases de colecciones son nuevas en Java 2. Con excepcin de las clases que han sido actualizadas como Vector y BitSet, si ejecutas cualquiera de las Colecciones a travs de un JDK antiguo, conseguirs un error en tiempo de compilacin. Respuesta 3) 1)La interface Set se diseo para asegurar que la implementacin de clases tengan miembros nicos Los elementos de una clase que implementa la interface List pueden contener elementos duplicados. Aunque una clase que implementa la interface Set podra usarse para guardar archivos retornados por una consulta a una base de datos, no se diseo particularmente para ese propsito. Respuesta 4) 2)Puedes crear una coleccin ordenada instanciando una clase que implemente la interface List Respuesta 5) 212

javaHispano. Tu comunidad, tu lenguaje.

4)Un arreglo Para semejante requisito sencillo probablemente un arreglo ser la mejor solucin. Respuesta 6) 2) HashMap 3) Vector A partir de Java 2 la clase Vector fue actualizado para ser parte del marco de trabajo de las colecciones. Respuesta 7) 4)Con el Mtodo remove

Otras Fuentes para este tema: El tutorial de SUN http://java.sun.com/docs/books/tutorial/collections/index.html Jyothi Krishnan cubre este tema en http://www.geocities.com/SiliconValley/Network/3693/obj_sec10.html#obj30

213

Tutorial para el examen de certificacin: SCJP 1.2

Seccin 11. El paquete java.io


Objetivo 1
Escribir cdigo que utilice objetos de la clase File para navegar dentro del sistema de archivos. En su excelente libro "Just Java and Beyond" Peter van der Linden comienza su captulo sobre I/O de ficheros diciendo: "No es justo remarcar, como han hecho algunos, que el soporte para I/O en Java es un punto muy importante". Yo creo que l estaba indicando que es levemente importante, y as, es un rea en la que hay que redoblar la comprobacin de tu conocimiento antes de ir al examen. Cuando lo estas aprendiendo te queda al menos la compensacin de que comprenders un rea til del lenguaje. El sistema I/O de java esta basado en el concepto de flujos streams . El termino computacional stream fue popularizado primeramente por el sistema operativo UNX y puedes considerar tomarlo como analoga de un flujo de agua. Puedes tener un stream viniendo de una sola salida y de ah aplicarle un filtro para procesarlo. Los nombres de las clases de flujos de I/O no son intuitivos y las cosas no siempre funcionan como las podras imaginar. La clase File La clase File no es del todo descriptiva, puesto que una instancia de la clase File representa el nombre de un archivo o directorio ms que el archivo en si mismo. Mi primera suposicin al pedrseme navegar en un sistema de archivos sera buscar un mtodo para cambiar de directorio. Desafortunadamente la clase File no tiene se mtodo y parece que simplemente tienes que crear una nueva instancia de File con un directorio diferente en su constructor. As el examen podra hacerte preguntas sobre la habilidad de crear y eliminar archivos y directorios, qu podra ser considerado bajo la cabecera de "navegacin por el sistema de ficheros".

Crear una instancia de la clase File no crea un archivo en el sistema operativo subyacente.

214

javaHispano. Tu comunidad, tu lenguaje.

La clase File ofrece el mtodo:


delete()

Para borrar un archivo o directorio.


mkdir() y mkdirs()

Para crear directorios. La clase File contiene el mtodo list(), que devuelve un arreglo de Strings conteniendo todos los archivos de un directorio. Esto es muy practico para comprobar si un archivo esta disponible antes de intentar abrirlo. Un ejemplo del uso de list():
import java.io.*; public class FileNav{ public static void main(String argv[]){ String[] filenames; File f = new File("."); filenames = f.list(); for(int i=0; i< filenames.length; i++) System.out.println(filenames[i]); } }

Esto sencillamente muestra una lista de todos los archivos en el directorio actual ("*.*") Independencia de plataforma La clase File esta escrita en Java puro. Esto significa que no incluye cdigo nativo, pero tambin significa que esta escrito para funcionar independientemente de la plataforma sobre la cual se ejecute. Debido a las diferencias en la manera en que trabajan los distintos sistemas de archivos es importante estar consciente de particularidades de la plataforma como el carcter separador de los directorios. En Win/DOS es la barra invertida \ , en UNX es la barra normal / y sobre MAC es otro. Puedes saber cual es este carcter dependiente de la plataforma utilizando la constante File.separator en lugar de obtenerlo con alguna codificacin compleja. Un programa para navegar por el sistema de archivos El siguiente archivo es bastante largo (ms de 90 lneas) pero para entenderlo, necesitaras conocer la mayora de los objetivos que se explican en esta seccin. El programa te permite navegar entre los archivos de un directorio y cambiar de directorio. Esta inspirado en parte en cdigo del libro "Java in a Nutshell" de Oreilly. Un libro que recomiendo ampliamente. Aqu una muestra del programa en funcionamiento.

215

Tutorial para el examen de certificacin: SCJP 1.2

import java.awt.*; import java.awt.event.*; import java.io.*; public class Filer extends Frame implements ActionListener{ /************************************************************** Marcus Green October 2000 Part of the Java Programmer Certification tutorial available at http://www.jchq.net. Addressing the objective to be able to use the File class to navigate the File system.This program will show a list of files in a directory .Clicking on a directory will change to the directory and show the contentsNote the use of File.separator to allow this to work on Unix or PC (and maybe even the Mac) ****************************************************************/ List lstFiles; File currentDir; String[] safiles; int iEntryType = 6; int iRootElement = 0; int iElementCount = 20; public static void main(String argv[]){ Filer f = new Filer(); f.setSize(300,400); f.setVisible(true); }

216

javaHispano. Tu comunidad, tu lenguaje.


Filer(){ setLayout(new FlowLayout()); lstFiles = new List(iElementCount); lstFiles.addActionListener(this); //set the current directory File dir = new File(System.getProperty("user.dir")); currentDir = dir; listDirectory(dir); add(lstFiles); addWindowListener( new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } } ); } public void actionPerformed(ActionEvent e){ int i = lstFiles.getSelectedIndex(); if(i==iRootElement){ upDir(currentDir); }else{ String sCurFile = lstFiles.getItem(i); //Find the length of the file name and then //chop of the filetype part (dir or file) int iNameLen = sCurFile.length(); sCurFile = sCurFile.substring(iEntryType,iNameLen); File fCurFile = new File(currentDir.toString()+File.separator sCurFile); if(fCurFile.isDirectory()){ listDirectory(fCurFile); } } } public void upDir(File currentDir){ File fullPath = new File(currentDir.getAbsolutePath()); String sparent = fullPath.getAbsoluteFile().getParent(); if(sparent == null) { //At the root so put in the dir separator to indicate this lstFiles.remove(iRootElement); lstFiles.add(" "+File.separator+" ",iRootElement); return; }else{ File fparent = new File(sparent); listDirectory(fparent); } } public void listDirectory(File dir){ String sCurPath = dir.getAbsolutePath()+File.separator ; //Get the directorie entries safiles = dir.list(); //remove the previous lis and add in the entry //for moving up a directory

217

Tutorial para el examen de certificacin: SCJP 1.2


lstFiles.removeAll(); lstFiles.addItem("[ .. ]"); String sFileName = new String(); //loop through the file names and //add them to the list control for(int i=0; i< safiles.length; i++){ File curFile = new File(sCurPath + safiles[i]); if(curFile.isDirectory()){ sFileName = "[dir ]" + safiles[i]; }else{ sFileName = "[file]"+safiles[i]; } lstFiles.addItem(sFileName); } add(lstFiles); currentDir=dir; } }

Preguntas Pregunta 1) Cul de los mtodos siguientes sirve para distinguir entre un directorio y un archivo? 1) FileType() 2) isDir() 3) isDirectory() 4) getDirectory() Pregunta 2) Cul de los siguientes mtodos de la clase File borrar un directorio o un archivo al ejecutarse? 1) La clase File no te permite borrar un archivo o un directorio 2) remove() 3) delete() 4) del() Pregunta 3)

218

javaHispano. Tu comunidad, tu lenguaje. Cmo puedes obtener los nombres de los archivos contenidos dentro de una instancia de la clase File con el contenido del directorio actual 1) dir.list() 2) dir.list 3) dir.files() 4) dir.FileNames() Pregunta 4) Cul de las siguientes lneas llenar una instancia de la clase File con el contenido del directorio actual? 1) File 2) File 3) File 4) File
f f f f = = = = new new new new File(); File("*.*"); File('*.*'); File(".");

Pregunta 5) Dada la siguiente lnea de cdigo:


File f = new File("myfile.txt");

Qu mtodo crear el archivo myfile.txt en el sistema operativo subyacente? 1) f.write(); 2) f.close(); 3) f.flush(); 4) Ninguno de los anteriores Pregunta 6) Cul de las siguientes lneas cambiar el directorio actual al que se encuentra en un nivel superior? 1) chDir(".."); 2) cd("."); 3) up(); 4) Ninguno de los anteriores Pregunta 7)

219

Tutorial para el examen de certificacin: SCJP 1.2 Cules de los siguientes son mtodos o campos de la clase File? 1) getParent() 2) separator 3) dirname 4) getName(); Respuestas Respuesta 1) 3) isDirectory() Respuesta 2) 3) delete() Respuesta 3) 1) dir.list() El mtodo list retorna un arreglo de Strings que contendr el contenido del directorio actual. Respuesta 4) 4) File f = new File("."); Este constructor para la clase File obtendr el contenido del directorio actual sobre sistemas de archivos como DOS o UNIX, pero no estoy seguro que ocurrir sobre otros sistemas con una estructura de archivos extica como Mac OS. Respuesta 5) 4) Ninguno de los anteriores La clase File principalmente describe un archivo que debe de existir. Para crear un archivo en el sistema operativo subyacente necesitas pasar una instancia de la clase File a una instancia de una de las clases OutputStream. Respuesta 6) 4) Ninguno de los anteriores

220

javaHispano. Tu comunidad, tu lenguaje. Java no tiene una manera directa para cambiar el directorio actual. Una manera indirecta es crear una nueva instancia de la clase File apuntando al directorio deseado. Respuesta 7) 1) getParent() 2) separator 4) getName();
Otras Fuentes para este tema:

Puedes darle un vistazo a los ejemplos del libro de I/O de O'Reilly: http://metalab.unc.edu/javafaq/books/javaio/index.html Este tema se cubre en el tutorial de SUN en http://java.sun.com/docs/books/tutorial/essential/io/ La API de la clase File http://java.sun.com/products/jdk/1.2/docs/api/java/io/File.html El JLS sobre IO, un poco acadmico http://www.infospheres.caltech.edu/resources/langspec-1.0/javaio.doc.html Richard Baldwin sobre I/O http://home.att.net/~baldwin.rg/Intermediate/Java060.htm Joyothi tiene varias tiles tablas sobre las clases de I/O en http://www.geocities.com/SiliconValley/Network/3693/io.html

221

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 2
Escribir use objetos de las clases InputStreamReader y OutputStreamWriter para traducir entre cdigos de caracteres UNICODE y el nativo de plataforma o el ISO 8859-1. Me sorprendi que este objetivo no se enfatizara en el examen de JDK 1.2 puesto que se haba introducido la internacionalizacin y sta es una de las grandes caractersticas de Java. Es bonito vender software a mil millones de europeos y americanos pero mil millones de chinos seran un agradable mercado adicional (incluso si slo el 10% lo compran) ste es el tipo de objetivo con el que ni siquiera los programadores de Java experimentados pueden tener poca experiencia, As qu toma nota!. Codificacin de caracteres en Java: UTF y UNICODE Java utiliza dos sistemas muy parecidos de codificacin UTF y UNICODE. Java fue diseado desde abajo para tenrselas que ver con caracteres multibyte y puede tratar con inmensos nmeros de caracteres que pueden guardarse usando el sistema de codificacin UNICODE. Los caracteres UNICODE son almacenados en 2 bytes permitiendo almacenar arriba de 65K caracteres. Esto le permite ser usado con alfabetos no occidentales. Esto significa que puede manipular chino y japons, y casi cualquier otro conjunto de caracteres conocido. Estars agradecido de saber que no tienes que dar ejemplos de nada de esto en el examen. Aunque UNICODE puede representar casi cualquier carcter que llegues a usar en tu vida, no es un mtodo eficiente de codificacin para programar. La mayora del texto dentro de un programa usa el cdigo ASCII, la mayora de este puede guardarse fcilmente dentro de un byte. Por razones de tamao, Java utiliza un sistema de codificacin llamado UTF8 para las literales de cadena, identificadores y otro texto dentro del programa. Esto puede dar como resultado un ahorro considerable de espacio comparndolo con el uso de UNICODE donde cada carcter requiere 2bytes. Las clases StreamReader La clase StreamReader convierte una entrada de bytes (no relacionada con un conjunto de caracteres) en un flujo de entrada de caracteres, uno que tenga el concepto de conjunto de caracteres. Si solo te las tienes que ver con conjuntos de caracteres de tipo ASCII, probablemente solo usars clases Reader en la forma de:
InputStreamReader(InputStream in)

cdigo

que

222

javaHispano. Tu comunidad, tu lenguaje. Esta versin usa el cdigo de caracteres nativo de la plataforma. En el JDK1.1 este valor por defecto se identifica por medio de la propiedad del sistema file.encoding. La codificacin predeterminada generalmente es ISO-Latin 1 excepto en Mac donde es MacRoman. Si esta propiedad del sistema no esta definida, el identificador del cdigo estndar es 8859_1 (ISO-LATIN-1). La suposicin parece ser: si todo lo dems falla, debes volver al ingls. Experimentar con otros juegos de caracteres es problemtico, debido que los caracteres no pueden mostrarse correctamente si el entorno no se configura apropiadamente. As si intentas mostrar un carcter del conjunto de caracteres chinos tu sistema quiz no lo soportar Si te las tienes que ver con otros conjuntos de caracteres puedes usar
InputStreamReader(InputStream in, String encoding);

Las clases StreamReader y Writer pueden tomar cualquier codificacin de caracteres como parmetro o puedes usar la codificacin predeterminada.

Recuerda que el InputStream viene primero y el cdigo de caracteres despus. Los mtodos read y write La clase InputStreamReader tiene un mtodo llamado read() y la clase OutputStreamWriter tiene un mtodo llamado write() que permiten leer y escribir caracteres respectivamente. Cuando se llama al mtodo read este lee bytes desde el stream de entrada y los convierte a caracteres UNICODE usando la codificacin especificada en el constructor del stream. Cuando se llama al mtodo write() los caracteres que vienen del stream son convertidos en su correspondiente byte codificado y es almacenado en un buffer interno. Cuando el buffer se llena, el contenido se escribe en el stream de bytes de salida. Ejemplo. GreekWriter El cdigo para esta clase escribe un archivo de salida contiene algunas letras en alfabeto griego. Si intentas abrir el archivo Out.txt con un editor, veras algo parecido a basura.
import java.io.*; class GreekWriter { public static void main(String[] args) { String str = "\u03B1\u03C1\u03B5\u03C4\u03B7"; try { Writer out = new OutputStreamWriter(

223

Tutorial para el examen de certificacin: SCJP 1.2


new FileOutputStream("out.txt"), 8859_7"); // 8859_7 is the ISO code for ASCII plus greek, // although this // example also works on my machine if it is set to UTF8 out.write(str); out.close(); } catch (IOException e) { e.printStackTrace(); }

Ejemplo. GreekReader
import java.io.*; import java.awt.*; class GreekReader extends Frame{ /******************************************************* *Companion program to GreekWriter to illustrate *InputStreamReader and OutputStreamWriter as part *of the objectives for the Sun Certified Java Programmers *exam. Marcus Green 2000 *********************************************************/ String str;

public static void main(String[] args) {


GreekReader gr = new GreekReader(); gr.go(); gr.setWin();

} public void go(){

try { FileInputStream fis = new FileInputStream("out.txt"); InputStreamReader isr = new InputStreamReader(fis,"8859_7"); Reader in = new BufferedReader(isr); StringBuffer buf = new StringBuffer(); int ch; while ((ch = in.read()) > -1) { buf.append((char)ch); } in.close(); str = buf.toString(); } catch (IOException e) { e.printStackTrace(); } } public void paint(Graphics g) { //paint method automatically called by the system Insets insets = getInsets(); int x = insets.left, y = insets.top; //Add 30 to y or we will only see the

224

javaHispano. Tu comunidad, tu lenguaje.


//downstrokes of the letters g.drawString(str, x, y +30);

} public void setWin(){ //Nice big font so we can see the characters. Font font = new Font("Monospaced", Font.BOLD, 59); setFont(font); setSize(200,200); setVisible(true); //Show the frame show(); } }

GreekReader en ejecucin.

Preguntas Pregunta 1) Cuales de las siguientes sentencias son verdaderas? 1) La clase OutputStream debe tomar una codificacin de caracteres como parmetro para su constructor. 2) La codificacin predefinida para la clase OutputStreamWriter es ASCII 3) Las clases InputStreamWriter y OuputStreamWriter puede tomar como parmetro para su constructor una codificacin de caracteres. 4) La clase InputStreanReader puede tomar un stream como uno de sus constructores. Pregunta 2) Cuales de las siguiente sentencias son verdaderas?

225

Tutorial para el examen de certificacin: SCJP 1.2 1) Java puede desplegar conjuntos de caracteres independientemente del sistema operativo subyacente. 2) La clase InputStreamReader puede tomar una instancia de otra clase InputStream como constructor. 3) Un InputStreamReader puede actuar como constructor de un OutputStreamReader para hacer conversiones entre juegos de caracteres. 4) Java usa el cdigo ASCII para almacenar cadenas internamente. Pregunta 3) Cuales de las siguientes son firmas validas para la clase InputStreamReder? 1) InputStreamReader(InputStream in, String encoding); 2) InputStreamReader(String encoding,InputStream in); 3) InputStreamReader(String encoding,File f); 4) InputStreamReader(InputStream in); Pregunta 4) Cuales de los siguientes son mtodos de la clase InputStreamReader? 1) read() 2) write() 3) getBuffer() 4) getString() Pregunta 5) Cuales de las siguientes son sentencias son verdaderas? 1) Java utiliza UNICODE para almacenar internamente literales de cadena 2) Java utiliza ASCII para almacenar internamente literales de cadena 3) Java utiliza UTF-8 para almacenar internamente literales de cadena 4) Java utiliza la codificacin nativa de la plataforma para almacenar internamente literales de cadena Respuestas Respuesta 1) 2) La codificacin predefinida para la clase OutputStreamWriter es ASCII 4) La clase InputStreanReader puede tomar un stream como de sus constructores. Respuesta 2) 1) Java puede desplegar conjuntos de caracteres independientemente del sistema operativo subyacente. 2) La clase InputStreamReader puede tomar una instancia de otra clase InputStream como constructor.

226

javaHispano. Tu comunidad, tu lenguaje. Aunque Java puede guardar caracteres independientemente del sistema operativo subyacente, el conjunto de caracteres apropiado debe instalarse para poder desplegar esos caracteres. Generalmente los streams son unidos con otros streams, por ejemplo un InputStream toma como constructor a otro InputStream y un OutputStream toma como constructor a otro OutputStream. Java utiliza el sistema de codificacin UTF para almacenar internamente cadenas. Respuesta 3) 1) InputStreamReader(InputStream in, String encoding); 4) InputStreamReader(InputStream in); Si no especificas una codificacin la JVM asumir como codificacin la predeterminada de la plataforma. Respuesta 4) 1) read() Respuesta 5) 3) Java utiliza UTF-8 para almacenar internamente literales de cadena
Otras Fuentes para este tema:

La documentacin de Sun sobre las clases InputStreamReader y OutputStreamWriter: http://java.sun.com/products/jdk/1.2/docs/api/java/io/OutputStreamWriter.html http://java.sun.com/products/jdk/1.2/docs/api/java/io/InputStreamReader.html JavaCaps: http://www.javacaps.com/sjpc_io_obj2.html Todo lo que puedes querer saber sobre UNICODE: http://www.unicode.org/

227

Tutorial para el examen de certificacin: SCJP 1.2

Objetivo 3
Distinguir entre las condiciones bajo las cuales se usara conversin al cdigo nativo de plataforma y las condiciones bajo las cuales se usara una conversin especfica. Este podra ser un objetivo de "bondad y disciplina". Con esto quiero decir que algunos puritanos podran tomar la actitud de que siempre deberas especificar el cdigo de conversin de caracteres porque nunca sabes donde, cuando y como se usar tu programa. Esto es porque muchos programadores asumieron que su cdigo nunca tendra que vrselas con el problema del ao 2000 por el que hubo tanto lo. Bien, es un buen pago para algunos programadores. Si tomas un punto de vista ms benigno, este objetivo te pide identificar si tu cdigo esta preparado para enfrentarse a un cdigo de caracteres no estndar. Si tu cdigo de caracteres por defecto no es ISO-LATIN-1 y consideras que el ingls es el lenguaje estndar para los negocios, o si necesitas manipular distintos cdigos de caracteres, entonces aprovchate de la posibilidad de hacer conversiones especficas. Si algo de esto no significa nada para ti, vuelve a leer la seccin anterior sobre las clases de lectura y escritura de archivos.

Otras Fuentes para este tema:

La documentacin de Sun sobre la internacionalizacin: http://java.sun.com/docs/books/tutorial/i18n/text/stream.html http://java.sun.com/products/jdk/1.1/docs/guide/intl/ http://java.sun.com/docs/books/tutorial/i18n/index.html

228

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 4
Seleccionar los argumentos validos para los constructores de una lista de clases contenidas en el paquete java.io. El nfasis en este objetivo es que conozcas los argumentos validos para los constructores de estas clases. Lo mas relevante que se puede mencionar es que la clase RandomFile no toma algn stream como argumento para alguno de sus constructores. Estas clases toman instancias de otros streams como argumentos. As en el examen te pueden preguntar si alguna de ellas puede tomar una instancia de la clase File, un String con el nombre del archivo o la ruta del archivo, para ver si realmente conoces los argumentos vlidos para sus constructores. Un constructor valido ser algn tipo de stream ms otros posibles parmetros.

FileInputStream and OutputStream


Las clases FileInputStream y FileOuputStream tomen como parmetro principal para sus constructores alguna referencia a un archivo. Esta puede ser un String que contenga el nombre del archivo, una instancia de la clase File o una instancia de la clase FileDescriptor. Estas clases a menudo se utilizan como el primer paso para ligar clases de streams. Tpicamente una instancia de la clase FileInputStream recibe una referencia a un archivo-cualquiera de las que mencionamos anteriormente-, y se conecta con una instancia de la clase InputStreamReader para leer los caracteres que contiene dicho archivo. Este es un ejemplo de como se liga la clase FileInputStream con la clase InputStreamReader. Este programa mostrar su propio cdigo fuente.
import java.io.*; public class Fis{ public static void main(String argv[]){ try{ FileInputStream in = new FileInputStream("Fis.java"); InputStreamReader isr = new InputStreamReader(in); int ch=0; while((ch = in.read())> -1){ StringBuffer buf = new StringBuffer(); buf.append((char)ch); System.out.print(buf.toString()); } } catch (IOException e){System.out.println(e.getMessage());} } }

Lo anterior es aconsejable cuando programas en el mundo real y utilizas la clase InputStreamReader, este tipo de situaciones te permite implementa fcilmente la 229

Tutorial para el examen de certificacin: SCJP 1.2 internacionalizacin. Observa el ejemplo GreekReader.java mostrado anteriormente para ver un ejemplo de esto.

BufferedInputStream y BufferedOutputStream
Estas clases descienden directamente de las clases FilterInputStream y FilterOutputStream respectivamente. Permiten leer ms informacin de manera inmediata colocndola en un buffer. Esto incrementa la eficiencia, ya que es mucho ms rpido leer desde la memoria que desde el disco. Este tipo de lectura es particularmente til si tienes que estar leyendo una gran cantidad de datos. Un ejemplo puede ser cuando ests procesando varias decenas de Megabytes de texto. Las clases BufferedInputStream y BufferedOutputStream toman una instancia de las clases InputStream y OutputStream respectivamente como parmetro para alguno de sus constructores, pero tambin pueden tomar un parmetro adicional que defina el tamao del buffer. As, puedes ajustar el tamao del buffer que vas a utilizar. Este es un ejemplo de uso de las clases BufferedInputStream, observa como el cdigo es similar con el ejemplo anterior nicamente se substituye la lnea del InputStreamReader por BufferedInputStream.
import java.io.*; public class BufIn{ public static void main(String argv[]){ try{ FileInputStream fin = new FileInputStream("BufIn.java"); BufferedInputStream bin = new BufferedInputStream(fin); int ch=0; while((ch=bin.read())> -1){ StringBuffer buf = new StringBuffer(); buf.append((char)ch); System.out.print(buf.toString()); } } }catch(IOException e){System.out.println(e.getMessage());};

DataInputStream y DataOutputStream
Las clases DataInputStream y DataOuputStream se usan para leer de una manera portable representaciones binarias de los tipos de datos primitivos de java. Esto te da acceso a varios mtodos como readDouble o readInt que funcionarn de la misma manera sobre distintas plataformas. En el JDK 1.0 est era una de las principales maneras de acceder a texto UNICODE, pero desde la versin 1.1 del JDK ha sido substituido por las clases Reader . Esas clases toman una instancia de la clase Stream como parmetro de su constructor.

230

javaHispano. Tu comunidad, tu lenguaje. El siguiente ejemplo escribe un carcter en un archivo y despus lo lee y muestra en la consola.
//Write the file import java.io.*; public class Dos{ public static void main(String argv[]){ try{ FileOutputStream fos = new FileOutputStream("fos.dat"); DataOutputStream dos = new DataOutputStream(fos); dos.writeChar('J'); }catch(IOException e){System.out.println(e.getMessage());} } } //Read import public public the file java.io.*; class Dis{ static void main(String argv[]){ try{ FileInputStream fis= new FileInputStream("fos.dat"); DataInputStream dis = new DataInputStream(fis); System.out.println(dis.readChar()); }catch(IOException e){System.out.println(e.getMessage());} } }

La clase File
La clase File tiene tres versiones de constructores. Estos son:
File(String path); File(String path, String name) File(File dir, String name);

Los tres son muy similares y realizan la misma funcin. El primer constructor que toma un String recibe el nombre de un archivo, incluyendo su ruta, en forma de cadena. Esta ruta puede ser absoluta o relativa. El segundo toma por separado la ruta y el nombre del archivo y el tercer constructor es casi igual al primero excepto que el primer parmetro que indica el directorio del archivo es del tipo File en lugar del tipo String.

RandomAccesFile
Lo ms importante que debes saber sobre los constructores de esta clase, es que toman 2 parmetros para sus constructores y que el segundo parmetro es un String que contiene el modo de apertura del archivo. Ms adelante se explica con detalle.

231

Tutorial para el examen de certificacin: SCJP 1.2

Preguntas Pregunta 1) Cules de las siguientes clases con parmetros validos para los constructores de la clase FileInputStream? 1) File 2) String 3) FileDescriptor 4) RadomAccessFile Pregunta 2) Cules de los siguientes constructores son validos para la clase BufferedInputStream? 1) BufferedInputStream(FileInputStream in, int size) 2) BufferedInputStream(FileInputStream in) 3) BufferedInputStream(FileOutputStream fos) 4) BufferedInputStream(RandomAccessFile ram) Pregunta 3) Cules de los siguientes constructores son validos para la clase DataInputStream? 1) DataInputStream(FileInputStream in, int size) 2) DataInputStream(FileInputStream in) 3) DataInputStream(File f) 4) DataInputStream(String s) Pregunta 4) Dado el siguiente cdigo:
import java.io.*; public class Dos{ public static void main(String argv[]){ FileOutputStream fos = new FileOutputStream("fos.dat"); DataOutputStream dos = new DataOutputStream(fos); BufferedOutputStream bos = new BufferedOutputStream(dos);

232

javaHispano. Tu comunidad, tu lenguaje.


dos.write('8'); }

Cul de las siguientes sentencias es verdadera? 1) El cdigo no se compilar 2) No compilar debido a que la clase BufferedOutputStream no tiene un constructor que tome como parmetro una instancia de la clase DataOutputStream 3) Se compilara y escribir el byte 8 en el archivo 4) Se compilara y escribir la cadena 8 en el archivo Pregunta 5) Cules de los siguientes son constructores validos? 1) File(String path); 2) File(String path, String name) 3) RandomAccessFile(File) 4) File(RandomAccesFile name) Pregunta 6) Dado el siguiente cdigo:
import java.io.*;

public class Ppvg{

public static void main(String argv[]){ Ppvg p = new Ppvg(); p.go(); } public void go(){ try{ DataInputStream dis = new DataInputStream(System.in); dis.read(); }catch(Exception e){} System.out.println("Continuing"); } }

Cul de las siguientes sentencias es verdadera? 1) El cdigo se compilar y al ejecutarse se detendr hasta que se pulse una tecla 2) El cdigo no se compilar debido a que System.in es una clase esttica 3) El cdigo se compilar y se ejecutar sin generar ninguna salida 4) El cdigo no se compilar debido a que System.in no es parmetro para un constructor valido para la clase DataInputStream Respuestas 233

Tutorial para el examen de certificacin: SCJP 1.2 Respuesta 1) 1) File 2) String 3) FileDescriptor Respuesta 2) 1) BufferedInputStream(FileInputStream in, int size) 2) BufferedInputStream(FileInputStream in) Respuesta 3) 2) DataInputStream(FileInputStream in) Respuesta 4) 1) El cdigo no se compilar El cdigo no se compilar debido a que no se encuentra dentro de un bloque try/catch Respuesta 5) 1) File(String path); 2) File(String path, String name) Respuesta 6) 1) El cdigo se compilar y al ejecutarse se detendr hasta que se pulse una tecla Otras Fuentes para este tema La documentacin de las APIs en SUN Buffered I/O http://java.sun.com/products/jdk/1.2/docs/api/java/io/BufferedInputStream.html http://java.sun.com/products/jdk/1.2/docs/api/java/io/BufferedOutputStream.html Data I/O http://java.sun.com/products/jdk/1.2/docs/api/java/io/DataInputStream.html http://java.sun.com/products/jdk/1.2/docs/api/java/io/DataOutputStream.html

234

javaHispano. Tu comunidad, tu lenguaje.

Objetivo 5
Escribir el cdigo adecuado para leer, escribir o actualizar ficheros usando objetos FileInputStream, FileOutputStream y RandomAccessFile.

FileInputStream and FileOutputStream


El siguiente ejemplo crea un fichero de texto llamado Out.txt y escribe el texto "Hello" en l. Si abres el fichero resultante vers que contiene el texto "H e l l o" (con un espacio en blanco entre cada letra). Sospecho que es porque un carcter en Java es de 16 bits y uno en ASCII son 8 bits, los 8 bits de ms peso dan como resultado un carcter en blanco. Esto tambin muestra el objetivo previo de usar la clase DataOutputstream, descendiente de FilterOutputStream. Esto permite que sean escritos los caracteres legibles para el ser humano. Si este ejemplo solo usara mtodos de FileOutputStream estaras limitado a escribir bytes o enteros. Si haces esto y muestras el resultado por la consola, solo vers caracteres extraos.
import java.io.*; public class Fos{ String s = new String("Hello"); public static void main(String argv[]){ Fos f = new Fos(); f.amethod(); } public void amethod(){ try{ FileOutputStream fos = new FileOutputStream("Out.txt"); //DataOutputStream te permite escribir caracteres DataOutputStream dos = new DataOutputStream(fos); dos.writeChars(s); }catch(IOException ioe) {} } }

El siguiente ejemplo leer el fichero de texto producido en el ejemplo anterior y mostrar el texto en la consola. Date cuenta de que puesto que el programa anterior gener el fichero como UNICODE, si creas un fichero de texto con un editor de textos conteniendo una cadena de caracteres como "Hello", el siguiente cdigo probablemente slo mostrar caracteres extraos.
import java.io.*; public class Fis{

235

Tutorial para el examen de certificacin: SCJP 1.2


public static void main(String argv[]){ Fis f = new Fis(); f.amethod(); } public void amethod(){ try{ FileInputStream fis = new FileInputStream("Out.txt"); DataInputStream dis = new DataInputStream(fis); while(true){ char c =dis.readChar(); System.out.println(c); } }catch(IOException ioe) {} } }

RandomAccessFile
La clase RandomAccessFile esta desarrollada libremente y no encaja fcilmente dentro de las clases de flujos de I/O. Si en el examen encuentras respuestas que mezclan instancias de RandomAccessFile con otros flujos de datos, casi seguramente son respuestas errneas. El constructor de RandomAccessFile toma una instancia de la clase File o una cadena de caracteres, y un argumento indicando el modo de apertura. El argumento referente al modo de apertura puede ser "r" para solo lectura o "rw" para lectura y escritura. Memoriza estas dos opciones, que no te engaen en el examen con modos como "w", "ro" o "r+w"; A diferencia de la clase File, si intentas pasar el nombre de un archivo al constructor, RandomAccessFile intentar abrir el archivo. Si pasas nicamente el modo "r" como parmetro y el archivo no existe se lanzar una excepcin. Y si pasas como parmetro el modo "rw" se intentar crear el archivo desde el sistema operativo.

La clase RandomAccessFile no toma un stream como un parmetro para alguno de sus constructores..

Este ejemplo leer el fichero Out.txt creado por el ejemplo anterior Fos.java. Por culpa del byte superior en blanco (byte, no bit), el resultado muestra un signo de interrogacin con cada letra. 236

javaHispano. Tu comunidad, tu lenguaje.

import java.io.*; public class Raf{ public static void main(String argv[]){ Raf r = new Raf(); r.amethod(); } public void amethod(){ try{ RandomAccessFile raf = new RandomAccessFile("Out.txt","rw"); for(int i=0; i<10;i++){ raf.seek(i); char myc = raf.readChar(); //? mostrado para los bytes de mas peso, los superiores System.out.println(myc); } } catch(IOException ioe) {} }

Pregunta 1) Asumiendo que se ha escrito cdigo para el manejo de excepciones, Cules de las siguientes sentencias crear una instancia de la clase RandomAccessFile?
1)RandomAccessFile 2)RandomAccessFile 3)RandomAccessFile 4)RandomAccessFile raf raf raf raf = = = = new new new new RandomAccessFile("myfile.txt","+rw"); RandomAccessFile( new DataInputStream()); RandomAccessFile("myfile.txt"); RandomAccessFile( new File("myfile.txt"));

Pregunta 2) Cuales de las siguientes sentencias son verdaderas? 1) La clase RandomAccessFile permite moverte hacia adelante y hacia atrs de un archivo sin tener que re-abrirlo. 2) Una instancia de la clase RandomAccessFile puede ser usada como parmetro para un constructor de la clase FileInputStream 237

Tutorial para el examen de certificacin: SCJP 1.2 3) Los mtodos de la clase RandomAccessFile no lanzan excepciones 4) Crear una instancia de la clase RandomAccessFile lanzar una excepcin si el archivo no existe Pregunta 3) Cuales de las siguientes sentencias son verdaderas? 1) La Clase FileInputStream puede tomar el nombre de un archivo o una instancia de la clase File como parmetros para alguno de sus constructores 2) La Clase FileInputStream lanzar una excepcin si el nombre del archivo pasado como parmetro al constructor no existe. 3) Los mtodos de la clase FileInputStream son apropiados especialmente para manipular archivos de texto. 4) El mtodo delete de la clase FileInputStream elimina un archivo desde el sistema operativo. Pregunta 4) Que pasar cuando intentes compilar y ejecutar el siguiente cdigo?
import java.io.*; public class Fos{ String s = new String("Hello"); public static void main(String argv[]){ Fos f = new Fos(); f.amethod(); } public void amethod(){ FileOutputStream fos = new FileOutputStream("Out.txt"); fos.write(10); } }

1) Error al compilar 2) Error al ejecutar 3) Se crear un archivo llamado Out.txt conteniendo el texto "10" 4) Se crear un archivo llamado Out.txt Pregunta 5) Cuales de las siguientes sentencias son verdaderas? 1) El mtodo seek de la clase FileInputStream define la posicin actual del puntero del archivo. 2) El mtodo read de la clase FileinputStream lee un nmero definido de bytes. 3) El mtodo get de la clase FileInputStream lee un nmero definido de bytes.

238

javaHispano. Tu comunidad, tu lenguaje. 4) Una instancia de la clase FileOuputStream se puede cerrar utilizando en mtodo close. Respuestas Respuesta 1) 1) RandomAccessFile raf = new RandomAccessFile("myfile.txt","+rw"); La clase RandomAccessFile es una anomala en la arquitectura de I/O de Java. Desciende directamente de Object y no es parte de la arquitectura de flujos de datos. Respuesta 2) 1) La clase RandomAccessFile permite moverte hacia adelante y hacia atrs de un archivo sin tener que re-abrirlo. 4) Crear una instancia de la clase RandomAccessFile lanzar una excepcin si el archivo no existe. Respuesta 3) 1) La Clase FileInputStream puede tomar el nombre de un archivo o una instancia de la clase File como parmetro para alguno de sus constructores 2) La Clase FileInputStream lanzar una excepcin si el nombre del archivo pasado como parmetro al constructor no existe. Las clases FileInputStream y FileOutputStream estn diseadas para leer y escribir bytes ms que texto. Respuesta 4) 1) Error al compilar
Fos.java:10: Exception java.io.IOException must be caught, or it must be declare in the throws clause of this method. FileOutputStream fos = new FileOutputStream("Out.txt");

Respuesta 5) 2) El mtodo read de la clase FileinputStream lee un nmero definido de bytes. 4) Una instancia de la clase FileOuputStream se puede cerrar utilizando en mtodo close.

239

Tutorial para el examen de certificacin: SCJP 1.2 Otras Fuentes para este tema Este tema esta cubierto por el tutorial de Sun en http://java.sun.com/docs/books/tutorial/essential/io/ El JLS sobre Java IO, un poco acadmico http://www.infospheres.caltech.edu/resources/langspec-1.0/javaio.doc.html Richard Baldwin sobre I/O http://home.att.net/~baldwin.rg/Intermediate/Java060.htm Oreilly ha publicado un libro especfico sobre Java I/O. Probablemente entra en ms detalle que el necesario para el examen de certificacin pero navegar por los ejemplos online te puede ayudar. El libro tiene generalmente buenas crticas en www.amazon.com http://www.oreilly.com/catalog/javaio/ Joyothi tiene varias tiles tablas sobre las clases de I/O en http://www.geocities.com/SiliconValley/Network/3693/io.html

240

You might also like