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.