jueves, 31 de diciembre de 2009

Feliz Año nuevo 2010

Al culminar este año les agradezco que hayan compartido con nosotros nuestro primer año en línea de "Acerca de Java".

Espero seguir compartiendo junto a ustedes siempre, esperando de sus comentarios y sugerencias para poder llevar un mejor servicio de estudio de la tecnología Java, con la bendición de Dios, la compañía de los ángeles y con todos ustedes lectores que son los principales protagonistas.

Para el año entrante 2010 espero sigamos adelante, haciendo uso de nuevas alternativas para compartir las técnicas de programación, también de innovaciones de esta tecnología, enlaces a otras páginas webs y blogs que puedan aclararnos las ideas y compartir el conocimiento que nos lleve a crecer como personas y a mejorar las condiciones de vida del ser humano.

Nos espera todavía mucho por recorrer, java es un lenguaje muy extenso y por eso hay tantos libros que lo abordan de distinta manera. Gracias a todos los que escriben por pasión al conocimiento, al libro de la WROX "Java JDK 6.0" (W. Clay Richardson y otros autores) de la cual he extraído algunas ideas para compartir, a DEITEL por su libro "Java, cómo programar" donde explican de forma clara, extensa y precisa la programación orientada a objetos en Java 1.4; por supuesto, también gracias al API de Java que es la guía de referencia de cualquier programador Java y por último a todos los blogs, foros y demás herramientas de internet que sirven para tener información de referencia y poder aclararla o extenderla. Es decir gracias a todos aquellos que directa o indirectamente aportan o hacen posible este servicio.

Y además, gracias de nuevo a ustedes por su compañía y apoyo.

¡Nos vemos en el 2010, Feliz Navidad y un 2010 lleno de amor y esperanza!

Les desea su servidor Kelvin Atencio a través de www.acercadejava.blogspot.com

martes, 22 de diciembre de 2009

Tenemos 2 de Argumentos variables y otras 2 más...

Nota: Si no ve bien las imágenes del código puede dar click en ella y esta se mostrará más fielmente en una nueva pantalla.

1.- ¿Cuál es el resultado de compilar y ejecutar el siguiente código?



[A].- Error de compilación
[B].- Se imprime 1
[C].- Se imprime 2
[D].- Se imprime 3
[E].- Se imprime 4
[F].- Se lanza una excepción en ejecución

2.- ¿Cuál es el resultado al compilar y ejecutar este código?
Suponga que en ejecución se pasan los parámetros de la siguiente manera:
>java PruebaVarArgs2 arg1 arg2 arg3



[A].- Se imprime "entro en arreglo"
[B].- Se imprime "entro en elipsis"
[C].- Se lanza IllegalArgumentException
[D].- Se lanza ArrayIndexOutOfBoundsException
[E].- El programa no puede compilar
[F].- Ninguna de las anteriores

3.- ¿Que se imprime al compilar y ejecutar el siguiente código?

[A].- This is the default outputtwentyten
[B].- twentyten
[C].- twenty
[D].- Error de compilacion
[E].- Excepción en ejecución

4.- ¿Qué se imprime en pantalla al compilar y ejecutar el siguiente código?

[A].- medidas finales (Alto: 50.0, Ancho: 20.0)
[B].- medidas finales (Alto: 60.0, Ancho: 30.0)
[C].- medidas finales (Alto: 80.0, Ancho: 20.0)
[D].- medidas finales (Alto: 80.0, Ancho: 30.0)
[E].- medidas finales (Alto: 60.0, Ancho: 20.0)
[F].- medidas finales (Alto: 50.0, Ancho: 30.0)

Respuestas Correctas:

1.- [D]. Se imprime 3.
Si, el compilador no tiene ninguna dificultad al compilar este código, pero en la ejecución como ambos métodos pueden ejecutar el código se le da prioridad al que recibe dos parámetros por defecto. Es decir si llamo a metodo(), o metodo(5), o metodo(1,8,7), se imprime 0, 1 y 3 respectivamente que es la longitud de z, pero al llamar a metodo(6,2) se ejecuta metodo(int x, int y) y por lo tanto se imprime 3 que es el resultado de 6 entre 2.

2.- [E]. El programa no puede compilar:
Esto debido a que el compilador interpreta tanto método String[] como String... como arreglos y por lo tanto el método está duplicado, por lo tanto el programa no compila.

3.- [B]. twentyten:
C
omo k vale 20, el programa imprime twenty, luego, como no existe un break, continúa abajo hasta case 10, por lo que imprime ten también. La compilación tiene efecto aunque default este de primero y aunque esté en cualquier parte de switch este sólo se ejecuta si ninguno de los case coincide.

4.- [C]. medidas finales (Alto: 80.0, Ancho: 20.0):
Java por defecto pasa los parámetros por valor. Para referencias y arreglos puedo cambiar el contenido pero no puedo asignarle una nueva referencia. Debido a esto, la línea 24 deja a rectangulo igual (50.0, 20.0), pero al llamar a cambiarAlto si cambia el valor dentro de la referencia y por lo tanto cambia el alto a 80.0, por lo tanto las medidas finales son Alto: 80.0 y Ancho 20.0

lunes, 30 de noviembre de 2009

Tres preguntas variadas

1.- Cuál es el resultado de compilar y ejecutar el siguiente código?



[A].- Imprime CAMain
[B].- Imprime ABCAMain
[C].- Imprime BCAMain
[D].- Imprime CBAAMain
[E].- Error de compilación
[F].- Excepcion en la ejecución


2.- Cual es el resultado al compilar y ejecutar el siguiente código?



[A].- 0123
[B].- 13
[C].- 1234
[D].- Error de compilación
[E].- Excepción en tiempo de ejecución

3.- Cual es el resultado al compilar y ejecutar el siguiente código?

[A].- Se imprime intenta, atrapa, finalmente y luego se lanza excepcion.
[B].- Error de compilación. Método main no debe lanzar (throws) Excepciones.
[C].- Error de compilación linea 17. No se puede lanzar excepcion en bloque finally.
[D].-Ninguna de las anteriores.


Respuestas:

1.- [C]: Debido a que cuando se crea el objeto C en la línea 19, se llama a los constructores por defecto de A, B y C, pero el constructor de A no hace nada (constructor por defecto), el método A que aparece allí es un método de clase ya que devuelve "void" (no es un constructor ya que tiene la palabra void), entonces al invocarse el constructor B se imprime B, luego se imprime C que es el constructor de C, y luego se invoca al mátodo A en la línea 20 por lo que se imprime A, para termina se imprime Main.

2.- [A]: Debido a que a es "true" esto hace que se entre en la estructura if sin verificar la segunda condición, es decir (++x) > 0. Por lo tanto se imprimen los valores que trae x por defecto del ciclo for.

3.- [D].- Como e1 = e está en una estructura catch el compilador no tiene la garantía de que esta sentencia se ejecute y por lo tanto se lanza una excepción en esta línea ya que el compilador no tiene la garantía que e1 sea inicializada.

jueves, 26 de noviembre de 2009

Tres preguntas de colecciones y genericos.

Ahora tengo tres preguntas que aunque cortas me parecen claves saber para la programación con Genéricos y Colecciones.

1.- Cuál es el resultado de compilar y ejecutar el siguiente programa?


[A].- 15.09
        1.0
        1.0
        2.0
[B].- 15.09
        1.0
        2.0
[C].- 15.09
        1
        1
        2
[D].- 15.09
        1.0
        1
        2
[E].- Error de compilacion

2.- Qué opción se debe colocar en la línea 6 donde aparece XXXX (las 4 xs) para que el programa compile?



[A].- Object[ ]
[B].- Integer[ ]
[C].- int[ ]
[D].- cualquiera de las anteriores
[E].- A o B
[F].- B o C


3.- Cuál es el resultado de compilar y ejecutar el siguiente código?




[A].- truetrue
[B].- truefalse
[C].- falsetrue
[D].- falsefalse
[E].- Error de compilación
[F].- Exception en tiempo de ejecución

RESPUESTAS.-
1.-[E] Hay un error de compilación en la linea 14 debido a que no puedo asignar un objeto ArrayList<Double> a uno ArrayList<Object> ya que en genericos no hay relación de superclase y subclase, es decir se comportan como objetos distintos. Si se quisiera realizar esta operación puede cambiar la línea 5 de List<Object> a List<?> (Comodín) para mas información consulte el artículo de Genéricos Aquí

2.-[A] el método toArray() de List devuelve un arreglo de tipo Object[ ].

3.-[E] Si se desea saber si un objeto TreeSet o Collection debe usarse las colecciones pero sin los tipos de datos parametrizado, algo como:
coleccion instanceof TreeSet
coleccion instanceof Collection
No se puede saber si es una instancia de un genérico parametrizado.

sábado, 31 de octubre de 2009

Ahora son 4 preguntas.

Nota: Si deseas ver mejor la imagen puedes hacer click sobre ella.

1.- ¿Cuál es el resultado de compilar y ejecutar el siguiente código?


[A].-Error de compilación en línea 6. El constructor no puede tener valor de retorno.
[B].-El programa compila pero lanza un error en tiempo de ejecución en línea 13, ya que se intenta cambiar un valor constante.
[C].-Se imprime 35
[D].-Se imprime 55
[E].- Error de compilación en línea 13, mala llamada al constructor.
[F].-Ninguna de las anteriores

2.- ¿Cuál es el resultado de compilar y ejecutar el siguiente código?

[A].- El programa compila y ejecuta sin problemas. No se genera salida.
[B].- ClassCastException en tiempo de ejecución.
[C].- Error en la compilación.
[D].-Ninguna de las anteriores.

3.- ¿Qué resulta al compilar y ejecutar el siguiente código?. Suponga que las aserciones están ensambladas:

[A].- Error de compilación.
[B].- Sólo se imprime ABC.
[C].- Se imprime ABC y se lanza AsertionException.
[D].- Se impime ABC y se lanza AsertionError.


4.- ¿Cuál es la salida generada al ejecutar el siguiente código?


[A].- 123
000
123
[B].- 000
123
123
[C].- 123
123
000
[D].- 101202603
123
123
[E].- 000
123
[F].- 123
101202603
123

Respuestas Correctas:
1.- [F]:
Sucede un error de compilación, pero en la línea 7 debido a que en un método no constructor no puede cambiarse el valor de una constante (final) en este caso la variable final VALOR. La A es incorrecta ya que debido a que el método public int Ejecutable devuelve un entero se convierte en un método no constructor. B, C y D es incorrecta debido a que el sistema no compila.

2.- [C]:
No se puede castear dos clases que tengan el mismo padre, podría crearse una instancia de la clase padre llamado p, podriamos hacer p = (Hija2) h2; o h2 = (Padre) p; pero entre dos clases que tienen el mismo padre no puede haber un casteo.

3.- [A]:
Hay error de compilación debido a que en el método f la sentencia default del switch no tiene valor de retorno y tampoco lanza una exception. La aserción no es suficiente para el compilador.

4.- [B]:
Hagamos una traza del programa: Primero se ejecuta el método main que realiza una instancia de PruebaConstructor( ). Este constructor hace una llamanda al constructor con tres enteros pasando los valores 101, 202 y 603, a su vez este llama al método inicializar pasandole los valores recibidos. Al llegar al método inicializar se hace la primera impresión llamando a this.uno, this.dos y this.tres pero hasta este momento no han sido inicializados y por eso imprimen sus valores por defecto (tres ceros se imprimen en la línea 14). Luego en las líneas 15, 16 y 17, this.uno toma el valor 1, this.dos toma 2, y this.tres se le asigna 3, debido al operador ternario. Estos se imprimen en la línea 18, luego de esto se retorna el control a PruebaConstructor que recibe tres enteros, aquí no hay mas sentencias, se retorna a PruebaConstructor( ) que imprime 123 debido a la línea 6. Resultado respuesta B.

domingo, 25 de octubre de 2009

1. ¿Cual de las siguientes opciones son los códigos que deben colocarse en las líneas 3 y 10 respectivamente, para que la salida imprima "Buena Opcion"?


[A].- this.Interna.metodo1(); y this.Externa.metodo2();
[B].- new Interna().metodo1(); y new Externa().metodo2();
[C].- new Interna().metodo1(); y Externa.this.metodo2();
[D].- Interna.this.metodo1(); y Externa.this.metodo2();
[E].- this.Interna.metodo1(); y new Externa().metodo2();
[F].- new Interna().metodo1(); y this.Externa.metodo2();

2.- ¿Cuál es el resultado de compilar y correr el siguiente código?


[A].- imprime enteroCorto100
[B].- imprime puntoFlotante100
[C].- imprime doblePrecision100
[D].- Error de compilación. No hay constructor para entero.
[E].- Error en tiempo de Ejecución.

3.- ¿Cuál es la salida al compilar y ejecutar el siguiente código?



[A].- 0
[B].- 3
[C].- 4
[D].- 5
[E].- 6
[F].- Error de compilacion.

Respuestas Correctas:
1.-Respuesta correcta: C.
La opción A es incorrecta ya que Interna no es un campo de Externa ni viceversa, por lo tanto tampoco lo son las opciones E y F. La opción B, aunque compila lanza un StackOverflowError, debido a que en el constructor de Externa creo una instancia de Interna y dentro de Interna llama un constructor de Externa.
La opción D no es correcta ya que Interna.this.metodo1() se usa sólo si estoy dentro de una clase interna para llamar al método de la clase externa.
La opción correcta es la C, debido a que creo una nueva instancia de Interna en la clase externa y luego hago una llamada al metodo2 sin crear una nueva instancia.

2.-Respuesta correcta: B.
La respuesta correcta es B debido a lo que se llama promoción de argumentos, donde el tipo de cada valor en una expresión se promueve a su tipo "más alto" en la expresión.
las reglas de promoción son:
short o char --> int --> long --> float --> double:
Por lo tanto como no hay constuctor para int ni para long, entonces el valor es promovido hasta float porque este tiene constructor.

3.- Respuesta correcta: F.
La sentencia this() para llamar a otro constructor dentro de un constructor, debe ser la primera sentencia del mismo.

miércoles, 30 de septiembre de 2009

Nuevas Preguntas de ensayo para el SCJP 5.0

Saludos compañeros y bienvenidos de nuevo a un nuevo articulo de Acerca de Java. Allí van, tres preguntas más para nuestra preparación a la prueba SCJP 5.0.

1.- ¿Cuál es el resultado de compilar y ejecutar el siguiente código?[A].- El programa compila y ejecuta sin producir ninguna salida.

[B].- Error de compilación. Hace falta sincronización de metodo().

[C].- Error de compilación. Falta sentencia llamada al método notify() o notifyAll() en alguna parte del codigo.

[D].- Se lanza IllegalMonitorStateException en tiempo de ejecución

[E].- Ninguna de las anteriores

2.- En el siguiente código. ¿Cuál línea imprime false?


[A].- Línea 6.
[B].- Línea 7.
[C].- Línea 8.
[D].- Línea 9.
[E].- Más de una línea imprime false.
[F].- Ninguna de las anteriores

3.- ¿Cuál es el resultado de compilar y ejecutar el siguiente código?
[A].- Se imprime: CHAO Desde HOLA Hacia
[B].- Se imprime CHAO Desde Hacia HOLA
[C].- Se imprime HOLA CHAO Hacia Desde
[D].- Se imprime HOLA CHAO Hacia Desde HOLA
[E].- Error en tiempo de compilación.
[F].- Error en tiempo de ejecución.

1.- Respuesta correcta: D. IllegalMonitorStateException.
Se lanza IllegalMonitorStateException ya que el metodo wait() no se encuentra en un método sincronizado. La sincronización se verifica en tiempo de ejecución por lo tanto la opción B no es correcta como tampoco es necesario encontrar en el código una sentencia notify o notifyAll. El código compila pero lanza la excepción en ejecución.

2.- Respuesta Correcta: D. Línea 9.
Recordemos que el método equals verifica el contenido de las variables String y devuelve verdadero en caso de ser iguales, por otra parte == verifica que apunten al mismo objeto. Los objetos str1 y str2 apuntan al mismo objeto "Hola" por lo tanto arrojan verdadero en equals y ==, pero str3 aunque tiene el mismo contenido "Hola" no apuntan al mismo objeto ya que crea un nuevo objeto String a partir de str1, por lo tanto la línea 9 imprime false.

3.- Respuesta Correcta: A. Se imprime: CHAO Desde HOLA Hacia
TreeSet almacena objetos no duplicados en forma ordenada. Hay que recordar que HOLA aparece primero a Hacia a pesar de que la a primero está en el alfabeto, pero en sistema La O mayúscula aparece primero que la a minúscula y por lo tanto aparecerán en ese orden.

Es todo hasta ahora. Espero les haya gustado el artículo. Nos vemos en una próxima edición.

domingo, 20 de septiembre de 2009

Saludos compañeros y bienvenidos a mi nuevo artículo de Acerca de Java y, como lo prometido es deuda aquí van las primeras tres preguntas de Java:

1. ¿Cuál será el resultado de compilar y ejecutar el siguiente código?

A.- Se imprimer: "Valor de y: 0"

B.- Se imprime: "Valor de y: 1"

C.- Se imprime: "Valor de y: 2"

D.- Se imprime: "Valor de y: 3"

E.- Error de compilación línea 19: No se ha inicializado out.

F.- Ninguna de las anteriores

2.- ¿Cuál será el resultado de compilar y ejecutar el siguiente código?



A.- Error de compilación: Línea 9: No se puede lanzar excepción una vez atrapada.

B.- Se imprime:
Ejecuto metodo 1
Excepcion metodo 1
Excepcion metodo 2

C.- Se imprime:
Ejecuto metodo 1
Excepcion metodo 1
Excepcion metodo 2
Final metodo 1

D.- Se imprime:

Ejecuto metodo 1

Excepcion metodo 1

Final metodo 1

Excepcion metodo 2


E.- Compila bien, pero lanza excepción en tiempo de ejecución.

3.- ¿Cuál será el resultado de compilar y ejecutar el siguiente código?

A.- Error de compilación.

B.- Se imprime:

Constructor Clase 1

Primer constructor Clase 2

Constructor Clase 1

Llamada String


C.- Se imprime:

Primer constructor Clase 2

Llamada String

D.- Se lanza Excepción en tiempo de ejecución.



Respuestas:

1.- La respuesta es F. Esto debido a que el compilador cree que pudiera no inicializarse la variable "ye" (y) antes de imprimirla. Si se ve bien el código podrá verse que existen bloques if else if, pero no hay una sentencia else que indique al compilador que de alguna manera va a entrar a inicializar y, es decir, no hay error lógico debido a que sabemos que la variable y va a inicializarse ya que i toma o un valor menor a cero, mayor a cero o igual, pero no se lo estamos indicando al compilador, si cambiamos la línea 15 con una sentencia else eliminamos el error de compilación. y se de esa forma podría imprimirse 2, pero el compilador tal como está escrito no lo interpreta así.

2.- La respuesta es D. Según el orden en que se ejecuta el código tenemos: en el método main, se llama al método 2, que intenta ejecutar el método 1, aquí se imprime como primera línea "Ejecuto metodo 1", luego se lanza la excepción que es atrapada por el mismo método, se imprime "Excepcion metodo 1", luego se ejecuta el bloque finally que imprime: "Final metodo 1". Luego, se lleva al control al método 2 con lo que se llama Limpieza de la Pila ya que la excepción lanzada en la línea 9 no puede ser atrapada por método 1. Por ello se atrapa la excepción en el método 2 y se imprime: "Excepcion metodo 2".


3.- La respuesta es A: Al crear un constructor que recibe un parámetro entero en la Clase1 se elimina el constructor por defecto que no recibe parámetros, por lo tanto al crear un constructor en la clase derivada (Clase2) se debe recordar que la primera sentencia es la llamada al constructor de la super clase, si hay un constructor que no recibe parámetros en la super clase la llamada es implícita super(), pero en este caso no hay constructor por defecto y por lo tanto debe llamarse explícitamente al constructor de la super clase super(int) en la linea 9 antes de la sentencia System.out.println al igual que en la linea 13. Por ello hay error de compilación en el código de la pregunta 3.

lunes, 31 de agosto de 2009

Preparándonos para la certificación SCJP 5.0

Saludos compañeros y bienvenidos a un nuevo artículo de Acerca de Java. Hoy solo quiero dar la información acerca de los nuevos temas que vendrán.

Como preparación para nuestra prueba de certificación java, discutiremos de ahora en adelante acerca de preguntas comunes que suelen aparecer en nuestra prueba de certificación SCJP 5.0, los temas abarcan desde herencia, control de flujo, alcance de variables y métodos, tipos genéricos, nuevo ciclo for, arreglos, hilos, importaciones estáticas y otros temas que han sido discutidos, que son tomado en cuenta en la evaluación, pero ahora, en un contexto distinto ya que están enfocados ahora en preguntas de ensayo.

En estas preguntas hay que estar muy enfocado en los detalles ya que no siempre es lo que parece, si vemos detalladamente el código fuente vemos como debe ser el flujo de información y de allí sacar la respuesta correcta.

Para cumplir este objetivo se presentarán preguntas con opciones de respuesta, algunas de selección simple (una sola respuesta, utilizando RadioButton), otras de selección múltiple (utilizando CheckBox, indicando cuantas opciones debe marcar, tal como lo hace la prueba de certificación), y al final de esa pregunta una pequeña explicación de la(s) respuesta(s) correcta(s) indicando porque es esa y no las demás.

Recordando que nosotros los egresados de la 6ta promoción de Desarrolladores de Software de Maracaibo tenemos hasta el 31 de Diciembre de 2009 para presentar dicha prueba. Espero que están en contacto para discutir acerca de java, y poder ayudar para que podamos obtener buenas calificaciones en dicha prueba.

Gracias por seguir en contacto, recuerden que la sección de comentarios está disponible para cualquier pregunta, aporte o cualquier tema de Java que quieran compartir. Nos vemos en la próxima... Chao.

miércoles, 26 de agosto de 2009

Sistema de Registros de Java.

    A partir de la versión 1.4 de java2SE Sun microsystem agregó una función o concepto que permite controlar, dar formato y publicar mensajes a través de los llamados registros (log), pertenecientes al paquete java.util.logging.

    Éstos pueden emplearse para dar mensajes de información, estados de los datos o la programática o inclusive errores ocurridos durante la ejecución.

    Pueden beneficiar a varios empleadores de la aplicación como programadores, personal a cargo de realizar pruebas y por otra parte también a usuarios del sistema inclusive sino está asociado al código fuente.

    Utilizar los registros de java es muy simple, primero debe crear una referencia a Logger mediante la sentencia:

Logger registrador = Logger.getLogger(“NombreRegistro”);

Y luego crear el mensaje que desea mostrarse, por ejemplo:

registrador.log(Level.INFO, “Esta es la cadena que muestra el mensaje”);

Si agrega estas dos líneas a un método main ya obtiene resultados: Ejemplo;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Registrador {

   public static void main(String[] args) {
      Logger registrador = Logger.getLogger("Registrador");
      registrador.log(Level.INFO, "Mensaje de registro");
   }
}

Este programa emitirá algo parecido a esto:

26/08/2009 10:56:35 PM loggers.Registrador main
INFO: Mensaje de registro

Se puede notar acá que se ha creado un registro con nivel informativo (Level.INFO), esta es una constante de la clase Level que contiene además las siguientes:

SEVERE
Nivel de mayor prioridad, para indicar errores.
WARNING
Segundo nivel, indicados para advertencias
INFO
Indicados para mensajes con fines informativos
CONFIG
Para mensajes de configuración
FINE
Para información de la traza de la aplicación
FINER
Para información de rastreo de la traza de la aplicación
FINEST
Nivel más bajo y de menor prioridad

Además de estos 7 niveles, la clase Level contiene dos más para usos especiales como son:
OFF: para desactivar el sistema de registro (No muestra mensajes de ningún nivel)
ALL: Para activar o mostrar los mensajes de todos los niveles.

Existe una manera más directa de publicar un registro , ya que Logger posee un método por cada nivel de registro de tal forma que podremos hacer:

Logger registrador = Logger.getLogger("Nombre");
registrador.info("Mensaje informativo");
registrador.severe("Error grave");

Ahora veremos un ejemplo donde indicamos en el codigo fuente que sólo se muestren los registros a partir de cierto nivel, ejemplo, si escribo:

registrador.setLevel(Level.INFO);

Se mostrarán los registros a partir de info hasta los de mayor prioridad, es decir, info, warning y severe, o si colocamos Level.ALL, todos los registros o Level.OFF (desactiva loos registros). En conclusión, podemos utilizar setLevel para indicar desde que nivel mostraré los registros.

Ahora veamos un ejemplo completo de una clase que utiliza una referencia a los Registros:

import java.util.logging.Level;
import java.util.logging.Logger;

public class Registro {

   Logger logger;
   int nivel;

public Registro(String nombre){
   logger=Logger.getLogger(nombre);
}

public void setNivel(Level nivel){
   logger.setLevel(nivel);
}

public void dividir(){
   int num1 = 3, num2 = 0, division = 0;
   try{
      logger.log(Level.INFO, "Se va a dividir num1 y num2");
      division = num1 / num2;
   }catch (ArithmeticException e) {
      logger.log(Level.SEVERE, "Error. Division por cero");
   }catch (Exception e) {
      logger.severe("Excepcion ha sido lanzada");
}
}

public static void main(String[] args) {
   Registro registro = new Registro("Registrador");
   registro.setNivel(Level.ALL);
   registro.dividir();
}
}

Aquí se utiliza el método setNivel para cambiar el nivel para asignar a que se vean todos los registros a traves de setLevel(Level.ALL), si queremos desabilitar los registros colocariamos setLevel(Level.OFF). También se usaron los dos tipos de publicacion de registros como son logger.log(Level.SEVERE, "mensaje") y logger.severe("mensaje"). Si se ejecuta el codigo se verá como salida algo así:

26-ago-09 1:21:28 paquete.Registro mostrarRegistros
INFO: Se va a dividir num1 y num2
26-ago-09 1:21:28 paquete.Registro mostrarRegistros
SEVERE: Error. Division por cero

Bueno, eso es todo para la primera parte de registros en java. Nos vemos en una próxima edición.

jueves, 30 de julio de 2009

Aserciones en Java.

   Saludos de nuevo, ¡compañeros!. El tema que se discutirá ahora son las aserciones que permiten evaluar si nuestra aplicación se encuentra en los valores asumidos y cumple con lo esperado.

   Existe la posibilidad que incurramos en un error lógico de programación y el programa no esté arrojando los resultados que que esperamos, en estos casos se puede agregar una sentencia Java que permite evaluar una condicion booleana y arrojar mensajes de error. Si, es a través de las aserciones.

   La sintaxis general es:

assert ExpresionBooleana [: Expresion_que_expresa_el_error];

   Puede verse que existe una expresión booleana que es obligatoria, y una expresión que es opcional, durante la ejecución del programa, se evalúa primero la expresión booleana de ser verdadera el programa continúa ejecutándose como sino hubiese pasado nada, sino (de ser falsa) el programa lanza una AssertionError y escribe además la Expresion_que_expresa_el_error si existe una, sino existe soló lanza la excepción mencionada. La Expresion_que_expresa_el_error puede ser cualquier tipo de cadena, mensaje o valor que quiere mostrar para saber lo que sucedió. Después de esto el programa detiene su ejecución.

   La aserciones están inhabilitadas por defecto, para habilitarlas debe escribir en línea para ejecutar:

> java -ea NombrePrograma

donde ea son las siglas de "ennable assertions"

   Por ejemplo supongamos que el programa que usted realiza debe mantener siempre valores positivos en la variable radio (radio de un circulo), puede que haya incurrido en un error y dentro del programa y el radio toma valores negativos. Si agregamos la sentencia:

assert radio >= 0:"Error. Variable radio tomo un valor negativo";

   Al ejecutar esta sentencia Java y además habilitar las aserciones el programa evalúa la condicición booleana (radio >= 0) si es verdadera el programa continúa su ejecución normalmente en caso contrario lanza una AssertionError, imprimiendo el mensaje: "Error. Variable radio tomo un valor negativo" además de indicar de imprimir la traza de la pista del error (línea donde se encontró la aserción negativa y demás).

   Para mayor información verifique en la Página de Java. Programando con Aserciones

lunes, 13 de julio de 2009

Expresiones Regulares. II Parte

    Ahora que ya conocemos los metacaracteres, sus significados y reglas, veamos ahora como podemos utilizarlo para hacer que nuestras cadenas de caracteres puedan coincidir con los patrones:

La Clase Pattern: (Patrón):


    En las expresiones regulares de java la clase Pattern tiene varios métodos que nos sirven para establecer el patrón y buscar coincidencias, veamos:Métodostatic Pattern compile(String regex)
    Permite compilar una expresión regular para uso posterior como un patrón. Si la expresión regular tiene un error el compilador no permite la compilación.
El error mas común es: “Invalid escape sequence”.
Ejemplo:


Pattern patron = Pattern.compile("\w*");


Este código lanza un error ya que se deben colocar una barra invertida adicional para que la expresión \w tome efecto de la siguiente manera:

Pattern patron = Pattern.compile("\\w*");

Ahora si nuestro patrón está compilado y listo para usarse en cualquier parte del código, en este caso coincidirá con cualquier palabra que use sólo letras y/o números.

Método
static boolean matches(String regex, CharSequence input)
Sirve para hacer coincidir una expresión regular con una entrada, es muy útil si sabemos que la expresión regular se utilizará una sola vez.
Ejemplo:

System.out.println(Pattern.matches("\\w*","cadena2")); //Consola muestra true


Método
Matcher matcher(CharSequence entrada)
Devuelve un matcher que permitirá posteriormente buscar coincidencias con el patrón.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
Matcher m = patron.matcher("\t\t palabra");
if(m.matches()){
    System.out.println("Patron coincide");
}else{
    System.out.println("Patron No coincide");
}//Imprime Patron coincide


Método
String pattern()
Devuelve la expresión regular (como una cadena de caracteres) compilada por el método compile.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
System.out.println(patron.pattern());
//Se imprime \s*palabra


Método
String[] split(CharSequence entrada)
String[] split(CharSequence entrada, int limite)

Devuelve un arreglo de cadenas que resulta al separar la cadena entrada con la expresion regular, omitiendo la expresion regular.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
String[] cadenas = patron.split("uno palabra dos");
for(String fragmento: cadenas){
    System.out.print(fragmento.trim()+" ");
}
//Imprime uno dos

  La variante con límite, tiene tres modalidades, si límite es un entero positivo se aplicará al menos el límite menos 1 veces; si es cero, se aplicara tantas veces como se pueda eliminándose las cadenas vacías y por último
si es negativo es igual a cero pero se dejan las cadenas vacías.




    A continuación un código que utiliza las expresiones regulares para mostrar todas las clases que se encuentran dentro de un archivo java siempre y cuando la clase no extienda de ninguna clase y no implemente interfaces. La clase se llama Buscadora y cuando se va a utilizar hay que pasar como parámetro el archivo de clase al que se le quiere encontrar todas sus clases. Por ejemplo:

java Buscadora ClaseDestino.java

Aqui el codigo:


import java.io.*;
import java.util.regex.*;
import javax.swing.JOptionPane;

public class Buscadora {
  public static void main(String[] args) {
    BufferedReader entrada = null;
    String texto = "";
    String[] cadenas = null;
    Matcher m = null;
    Pattern patronBusqueda = Pattern.compile("\\s*\\w*\\s*\\w*\\s*class\\s*\\w*\\s*\\W*");
    Pattern patronSplit = Pattern.compile("\\s*\\w*\\s*\\w*\\s*class");

    try {
      File archivo = new File(args[0]);
      FileReader fr = new FileReader(archivo);
      entrada = new BufferedReader(fr);
      System.out.println(args[0]);
      while((texto = entrada.readLine()) != null){
        m = patronBusqueda.matcher(texto);
        if(m.matches()){
          cadenas = patronSplit.split(texto,0);
          for(String cadena: cadenas){
            cadena = cadena.replace("{", " ");
            cadena = cadena.replace("}", " ");
            if(cadena.trim().length() == 0)
              continue;
            System.out.println("Nombre de la clase: "+cadena.trim());
          }
        }
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      JOptionPane.showMessageDialog(null, "Debe especificar un archivo como paramentro");
    } catch (FileNotFoundException e) {
      JOptionPane.showMessageDialog(null, "Error. Archivo no encontrado");
    } catch (IOException e){
      JOptionPane.showMessageDialog(null, "Error al leer archivo");
    }
  }
}


    Como puede ver se utilizan dos patrones, uno para verificar que la línea que se compara coincida con una linea de declaración de una clase y el otro patrón para romper la cadena (split) y obtener así el nombre de la clase.

También es importante mencionar que el primer patrón (patronBusqueda) utiliza el metacaracter \W para hacerla coincidir con un caracter de no palabra, en este caso puede ser una llave "{" o "}". Otros utilizados son los caracteres de palabra \w y de espacio en blanco o tabulador \s.

martes, 30 de junio de 2009

Nuevos temas desde ahora

Saludos lectores, me he dado a la tarea de seguir buscando información acerca de las innovaciones de java 5.0, que son los temas que estamos desarrollando, a nivel de codificación no he visto otras innovaciones, se podría haber profundizado más por la extensión y tela que cortar que tiene java pero, por ahora, lo dejaremos hasta allí. Las innovaciones que he encontrado son a nivel de optimización de uso de recursos de hardware y reducción del tiempo de programación.

Ahora tomaremos otros temas que aunque son del jdk 1.4 no están obsoletos porque siguen vigentes en la versión 5. Los temas que se desarrollanrán son:

Expresiones Regulares (paquete java.util.regex),

Aserciones (Clase AssertionError del paquete java.lang)

Sistema de Registros de java (paquete lava.util.logging)

Comencemos:

Expresiones Regulares: I parte

Las expresiones regulares en Java son cadenas de texto que sirven de patrón para realizar búsquedas de otras cadenas buscando hacerlas coincidir con dicho patrón, los patrones generalmente contienen metacaracteres que permiten generalizar su significado, por ejemplo: Si queremos encontrar la palabra cuerpo podemos escribirla completamente y su significado será literal, pero si queremos buscar todas las cadenas que comiencen por c. ¿Cómo se hará? Si, la respuesta es con expresiones regulares.

Las expresiones regulares han tenido una evolución y permiten ahora un gran número de posibilidades para encontrar patrones dentro de cadenas. Las expresiones regulares en Java funcionan a través de tres elementos:

Metacaracteres

Patrón (Clase Pattern)

Verificador o Encajador (Clase Matcher)

Los metacaracteres son símbolos que tienen un significado diferente a su uso habitual, hemos dicho que si se quiere encontrar la palabra cuerpo podríamos escribirla (eso es literal), pero si escribo * en un patrón estoy buscando desde cero hasta cualquier número de caracteres del patrón especificado en la cadena, de tal manera que si coloco c\\w* en el patrón, se verificará si la cadena contiene una c, luego está seguida por cero o varios caracteres de palabra, de tal manera que coincide con carro, casa, coche y en fin palabras que comienzan por c.

Veamos una lista de los más comunes metacaracteres:

Metacaracteres Generales

Metacaracter

Significa

\

Elimina el significado literal del siguiente carácter siguiente

\t

Tabulador

\n

Nueva línea

\r

Retorno de carro

. (punto)

Un solo character. Ejemplo: “pas.”: coincide con pasa, pase, paso

Metacaracteres de limite

Metacaracter

Significa

Ejemplo

^

Que comience la línea por…

”^h\\w*”: Que la línea comience por la palabra con h. Nota: “^” tiene otro significado dentro de corchetes, ver más adelante

$

Final de línea

”\\w*\\.$”: línea que termina en punto (fin de párrafo), coincide con “palabra.” (palabra punto)

\b

Límite de palabra

Puede ser un espacio o retorno de carro.

\B

Límite de no palabra

Contrario a \b

\A

Comienzo de entrada

\\AH\\w*” coincide con “palabra de inicio de entrada”. “Hola”

Metacaracteres de letras

Metacaracter

Coincide con

\w

Cualquier carácter. Ya hemos dado varios ejemplos de este.

\W

No carácter.

\d

Un dígito (del 0 al 9)

\D

Lo que no sea dígito

\s

Espacio en blanco

\S

Un espacio no en blanco

Las expresiones regulares también permiten hacer coincidir con ciertos caracteres no predeterminados si estos se encierran entre corchete, de la siguiente manera:

[0123456789]: cualquier número, por lo tanto es el equivalente a \d.

[0-9]: igual al anterior pero expresado a manera de intervalo.

pas[ao]:coincide con pasa, paso, pero no con pase (entre corchete los dígitos que pueden coincidir).

Si quiero al contrario que no sea un elemento dentro del corchete se comienza dentro del corchete con circunflejo ^.

Per[^a]: no coincide con pera, pero si con Pero o Perú.

También podemos colocar varios intervalos:

[a-cA-C]: coincide con a, b o c minúsculas o mayúsculas.

La última característica que se verá en este artículo es la capacidad de las expresiones regulares de coincidir con determinado número de caracteres, ya vimos que el asterisco permite coincidir con cero o mas caracteres, veamos otros metacaracteres.

coincide con A cero o mas vences

Metacaracteres Generales

Metacaracter

Coincide con

A*

A cero o más veces

A?

A cero o una vez

A+

A una o más veces

A{n}

A n veces, n es un numero entero

A{n,}

A al menos n veces

A{n,m}

A entre n y m veces, ambos inclusive

Hasta aquí la primera parte del blog, en el siguiente artículo seguiremos hablando se las expresiones regulares y veremos ejemplos de código java.

viernes, 29 de mayo de 2009

Anotaciones en java 5

  Saludos y gracias por leer acerca de java, mi blog que en estos momentos desarrolla las ventajas e innovaciones de la programación con la versión 5 de java (J2SE 5.0). Espero le sea de ayuda.

  Ahora hablaremos de otra característica que fue agregada en java 5 que es la facilidad de metadatos a través de las llamadas anotaciones pertenecientes al paquete java.lang.annotation. Las mismas pueden utilizarse para generar o crear información adicional que beneficie tanto a los desarrolladores (documentando el código fuente, por ejemplo), como a usuarios de la aplicación que no están relacionados a la programación (metadatos en tiempo de ejecución). En anotaciones fue creado el concepto de retención, existe tres tipos de políticas de retención para las anotaciones:

    • SOURCE: la anotación sólo está disponible al momento de la programación, es decir, en el código fuente.
    • RUNTIME: la anotación puede estar disponible en tiempo de ejecución.
    • CLASS: Disponible en el archivo de clase, pero descartada en ejecución.

  En el JAVA API DE ANOTACIONES aparecen 4 anotaciones:

    • @Target: A quien podría o debe aplicarse la anotación.
    • @Documented: La anotación debe ser documentada por javadoc u otra herramientas de documentación.
    • @Inherited: Para heredar anotaciones de superclases, aunque no para interfaces.
    • @Retention:  Indica cuando va estar disponible la anotación, puede ser algunas de las tres políticas explicadas anteriormente:
@Retention(RetentionPolicy.SOURCE)
@Retention(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.CLASS)

  Pero además de estas cuatro que aparecen en el JAVA API existen otras dos más:

    • @Deprecated: Para marcar un método como desaprobado, no debe ser utilizado en la programación ya que de seguro puede generar problemas, aunque esté disponible.
    • @Override: Se coloca antes de un método y se utiliza para indicar al compilador que se sobrescribirá el método de la superclase y por lo tanto este método debe estar definido en la clase primaria, de no ser así se genera un error en tiempo de compilación.
  Vamos a lo que más creo necesario, veamos un código ejemplo:

public class ClasePadre{
  public void metodo(){
        System.out.println("Metodo clase padre invocado");
  }

  @Deprecated
  public static void metodoestatico(){
    System.out.println("Estatico Desaprobado");
  }

  public static void main(String[] args) {
    ClasePadre ce = new ClasePadre ();
    ce.metodo();
    metodoestatico();/*Metodo desaprobado*/
  }
}

class ClaseHija extends ClasePadre {

  public void metodo(int x){}
  @Override
  public void metodo(){}
  @Override
  public void metodo(String cadena) {}
}
  En el código anterior la clase padre no tiene problemas y debe compilar aunque use un método desaprobado (deprecated), pero la clase hija no, veamos porque. El primer método que recibe un parámetro entero no tiene problemas ya que aunque no es heredado de la clase padre, el compilador crea este método para la clase hija, el segundo tampoco tiene problemas ya que sobrescribe el método de la súper clase (tiene la misma firma), pero el tercero si genera un error de compilación ya que el código afirma que sobrescribirá el método de la clase padre pero la firma es distinta, aquí se genera un error de compilación.
Bueno, por ahora no tengo más que decir, nos “vemos” en una próxima edición.

miércoles, 29 de abril de 2009

La Clase Scanner de java 5.

La clase Scanner que se introdujo a partir de java 5 tiene varias utilidades. Puede separar o romper su dato de entrada en subcadenas o “tokens” y además convertir estos datos en tipos primitivos como enteros, flotantes, etc. Por ejemplo, puedo pasarle un dato String como argumento al constructor, definir su patrón delimitador (por defecto: espacio en blanco) y obtener subcadenas cuyos miembros debo recoger uno a uno mediante el método next() o algunos de sus similares (nextInt(), nextByte()… para cada dato primitivo existe un next()), veamos un pequeño programa:

public static void main(String[] args) {
    String cadena = "Blog_Acerca_de_Java";
    Scanner s = new Scanner(cadena);
    s.useDelimiter("_");
    while(s.hasNext()){
        System.out.println(s.next()); //s.next() devuelve cadena token
    }
}

En este programa se separarán en subcadenas separando por “_” y se muestra cada término en una línea en la consola de java. Este tipo de uso es muy similar a usar la clase StringTokenizer.
Por otro lado, la clase Scanner también tiene un constructor que recibe un InputStream, por lo que podemos pasarle al mismo la sentencia System.in para leer datos desde el teclado:

public static void main(String[] args) {
    System.out.print("Introduzca datos: ");
    Scanner s = new Scanner(System.in);
    System.out.println(s.next());
    System.out.println(s.nextInt());
    System.out.println(s.nextLine());
}

Este último código lee datos a partir del teclado, separa en subcadenas con espacio en blanco como delimitador, lee la primera cadena y la imprime en consola, espera un espacio, después busca el siguiente dato e intenta convertirlo a entero (int) si no puede hacerlo lanza un InputMismatchException y se detiene, de no lanzar la excepción lee el siguiente dato hasta el final de la línea y lo imprime.
Otro constructor que también nos beneficia es el que recibe un archivo como parámetro. Supongamos que tenemos un archivo con esta información:

Kelvin
30
78,7
Horario: 8am a 4pm

Los datos de este archivo pueden ser tratados mediante el siguiente programa:

public static void main(String[] args) {
    try {
        Scanner s = new Scanner(new File("archivo.txt"));
        System.out.println(s.nextLine());
        System.out.println(s.nextInt());
        s.nextLine();
        System.out.println(s.nextDouble());
        s.nextLine();
        System.out.println(s.nextLine());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (InputMismatchException e){
        e.printStackTrace();
    }
}

Recuerde colocar el archivo en la misma ruta el paquete del programa. Que fácil en comparación a los códigos de la versión anterior, ahora con la clase Scanner el manejo de archivos de acceso secuencial es mucho más fácil. Bueno, por ahora no tengo más que decir, espero esta información sea de utilidad, hasta una próxima edición.

Más información: Clase Scanner API Java

sábado, 18 de abril de 2009

Argumentos variables y System.out.printf() en Java 5.0 :

Java 5.0 introdujo la lista de argumentos variables mediante la elipsis, esto consiste en colocar tres puntos suspensivos después del tipo de dato en la declaración del método, en el último término (parámetro formal) del mismo de la siguiente manera:

public class ArgumentosVariables {

public ArgumentosVariables(){

System.out.println(sumar(2,3,4,5));

System.out.println(sumar(3,4));

}

public int sumar(int... valor){//Aquí está la elipsis

int resultado=0;

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

resultado+=valor[i];

}

return resultado;

}

public static void main(String[] args) {

ArgumentosVariables arg=new ArgumentosVariables();

}

}

La cantidad que puede recibir el método sumar puede estar entre cero a cualquiera, por lo tanto además de poder llamar al método sumar enviando dos enteros sumar(1,2) o 6 enteros sumar(1,2,3,4,5,6) también se podría llamar por sumar();y el método devolverá el resultado de la suma como resultado, ya que hace un recorrido por los valores de los argumentos (valor.length ) y suma cada término resultado+=valor[i].

Como se ha dicho, la elipsis sólo se acepta para el último término de la declaración del método, si se cambia la declaración del método sumar por el siguiente:

public int sumar(int... valor, String cadena){

Se arrojará el siguiente error de compilación:

“The variable argument type int of the method sumar must be the last parameter”.

Por lo tanto si puedo hacer:

public int sumar(String cadena, int... valor){

Bueno, en este tema no tengo más que explicar a menos que hayan dudas que quieran resolver por lo cual la parte de comentarios está abierta, por lo tanto he decidido hablar en este mismo artículo acerca del System.out.printf(); que utiliza las facilidades de los argumentos variables para imitar la capacidad de generar una salida por consola a la manera de lenguaje C, echemos un vistazo a la declaración del método printf:

printf (String format, Object... args)

Para los que no están familiarizados con el método, la cadena format indica la cadena que da formato de la salida y los objetos args son los valores que serán sustituidos en la cadena, veamos un ejemplo:

int suma=0, num1=7, num2=3;

suma=num1+num2;

System.out.printf("Al sumar %d mas %d, resulta: %d", num1, num2, suma);

//Salida generada: “Al sumar 7 mas 3, resulta: 10”;

En este caso el primer %d (%d significa numero entero) se sustituye con el primer valor ingresado después de la cadena (num1), luego, el segundo %d se sustituirá por el segundo entero y así sucesivamente, sino es así y por ejemplo se le pasa un valor double el programa compilará pero al ejecutarlo lanzará una java.util.IllegalFormatConversionException.

Si el número de variables de la cadena (tres ‘%d’ en el ejemplo) es menor al número de valores pasados como argumentos el programa compilará e ignorará los valores que están de más, pero si es mayor el programa compila pero arroja un java.util.MissingFormatArgumentException, ya que el número de valores pasados en los argumentos variables no satisface el número de valores esperados de la cadena.

Además de %d existen otros tipos por supuesto, a continuación tenemos los tipos con un ejemplo para cada uno:

%f: Para valores float o double:

System.out.printf("valor flotante: %f", 5.3f);// Salida “valor flotante: 5,300000”

%x.yf: Para float o double con formato ‘x’ dígitos ‘y’ decimales:

System.out.printf("valor pi: %6.4f", Math.PI);// Salida “valor pi: 3,1416” 6 dígitos, 4 decimales.

%x.ye %n: Para Notación científica: ‘x’ dígitos (incluyendo e+ o e-) ’y’ decimales

System.out.printf ("Notacion cientifica = %7.3e %n", 123456.0);//Salida “Notacion cientifica = 1.235e+05”

%o: Octal

System.out.printf("Octal: %o",25);// Salida “Octal: 31”

%h: Hexadecimal

System.out.printf("Hexadecimal: %h",255);

Espero información los ayude.

Bueno, por ahora es todo, hasta una próxima edición. Dios los bendiga.