Ir al contenido principal

Lo nuevo de Java 7

En julio de 2011 Mark Reinhold presentó la primera versión de de Java 7. Entre la versiones 5 y 6  no hubo grandes modificaciones ni del lenguaje ni de la VM pero la versión 7 sí que nos trajo cambios significativos. A la espera que Java 8 vea la luz en Octubre de este año, os presento una lista de 7 cambios de señor Java 7. La lista completa la podéis consultar aquí.




Cadenas en switchs

Si amigos por fin, no entiendo el motivo para no incorporar antes esta característica que tanto he echado en falta en multitud de ocasiones. Antes sólo lo podíamos utilizar con tipos básicos como char, byte, short, int,Character, Byte, Short, Integer o tipo enumerado (desde la versión 5). Ahora nos podemos olvidar de colocar sentencias if-else interminables y las comparación con el método equals de String, teniendo un código mucho más limpio y entendible.

public void testStringSwitch(String direction) {

        switch (direction) {

             case "up":

                 y--;

             break;



             case "down":

                 y++;

             break;



             case "left":

                 x--;

             break;



             case "right":

                 x++;

             break;



            default:

                System.out.println("Invalid direction!");

            break;

        }
    }

Antes cuando definíamos por ejemplo una lista genérica y queríamos instanciarla mediante su constructor debíamos indicar el tipo tanto en el momento de la definición como en el momento de instanciarla dinámicamente. Ahora ya no tendremos que indicarla en el momento de la asignación dinámica (en el constructor) porque se infiere de la definición del tipo.

Antes de Java 7:

List strings = new ArrayList();

En Java 7:

List strings = new ArrayList();

En casos de tipos más complejos puede ser muy útil no repetir de nuevo todos los tipos:

Gestión múltiple de excepciones

Antes teníamos que definir en varias sentencias try-catch el código para crear una instancia por Reflection, crear nuevos recursos como ficheros, etc... Ahora todo esto se puede compactar en una única línea separando las excepciones con el carácter "|".

Antes de Java 7:

try {
    Class a = Class.forName("wrongClassName");
    Object instance = a.newInstance();
} catch (ClassNotFoundException ex) {
    System.out.println("Failed to create instance");
} catch (IllegalAccessException ex) {
    System.out.println("Failed to create instance");
} catch (InstantiationException ex) {
   System.out.println("Failed to create instance");
}

Después de Java 7:


try {
    Class a = Class.forName("wrongClassName");
    Object instance = a.newInstance();
} catch (ClassNotFoundException | IllegalAccessException |
   InstantiationException ex) {
   System.out.println("Failed to create instance");
}

Try-Catch con gestión de recursos

En Java 7 tenemos la posibilidad de gestionar los diferentes recursos (File, Statement, ResultSet, Socket...) mediante sentencias try-catch sin tener que poner la sentencia finally. Dicha sentencia se utiliza para asegurar que se ejecuta un código determinado después de un bloque try-catch, bien se produzcan excepciones o  no. Normalmente aquí se cerraban los recursos que abríamos mediante el bloque try-catch, asegurando la correcta gestión de los diferentes recursos.

Antes de Java 7:


try {
            in = new BufferedReader(new FileReader("test.txt"));

            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (in != null) in.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

En Java 7:



       try (BufferedReader in=new BufferedReader(new FileReader("test.txt")))
       {
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }


Mejorada la API de IO

Hay varios cambios en el paquete java.nio, sobre todo relacionados con el rendimiento. También se han realizado mejoras del paquete java.io (sobre todo de la clase java.io.File), lo que ha desencadenado que se crease un nuevo paquete (java.nio.file).

Entre las las clases más relevantes de este paquete están:
  • java.nio.file.Path. Interfaz que sustituye a la clase java.io.File.
  • java.nio.FileSystem. Para obtener las rutas de los diferentes ficheros.
  • java.nio.FileSystems. Factoría con la que se puede obtener una instancia de FileSystem mediante el método getDefault().
  • java.nio.Files. Contiene los métodos estáticos necesarios para las operaciones con ficheros. Por ejemplo, abajo podemos ver como podemos leer todas las líneas de un fichero y guardarlas en una lista mediante el método readAllLines. Con esta clase también podemos crear enlaces simbólicos a ficheros (imposible antes de Java 7). Otra característica que se añade en Java 7 es la posibilidad de establecer permisos de ficheros en una sistema de ficheros compatible con POSIX mediante el método Files.setPosixFilePermissions. Antes de esto sólo se podía haver mediante la interfaz JNI o mediante 'hackeos' con System.exec()
Mediante la API del WatchService también podemos recibir notificaciones sobre diferentes elementos. Por ejemplo, podemos indicar que se nos notifique cuando se creeen ficheros, modifiquen o se borren ficheros en un directorio del sistema de ficheros determinado. 

Ejemplo de lectura de fichero con Java 7:


List lines =  Files.readAllLines(
       FileSystems.getDefault().getPath("test.txt"), StandardCharsets.UTF_8);

       for (String line : lines) System.out.println(line);

Soporte para lenguajes no Java (invokedynamic)

En la versión 7 hay una nueva instrucción a nivel de bytecodes llamada invokedynamic. Esta instrucción no podrá ejecutarse desde Java pero será muy útil para los lenguajes dinámicos que corran bajo la JVM.

En un lenguaje con tipado estático como Java todos los tipos de las variables se conocen en tiempo de compilación mientras que en un lenguaje tipado dinámicamente como JRuby, Groovy,... esto no es así. 

Cuando en un lenguaje dinámico que corre bajo la JVM invocamos un método de un objeto que desconoce, se invoca ese método a nivel de bytecode mediante la reflection de Java. 

A modo de ejemplo, en un lenguaje dinámico llamaríamos al método de un objeto desconocido de esta forma: 

def veamos( objeto )
    objeto.salvar()
end

Que en un lenguaje Java sería algo similar a hacer esto:

Method m = objeto.getClass().getMetodo("salvar");
m.invoke( objeto )

Actualmente hay varios tipos de reflexión en Java:

  • invokevirtual. Para llamar a un método de un objeto.
  • invokeinterface. Para llamar a métodos de interfaces (objeto debe implementar interfaz).
  • invokestatic. Para llamar a un método de una clase.
  • invokespecial. Para llamar a constructores.
Con Java 7 se añade invokedynamic, para llamar a un método de un objeto desconocido. Esto hará que a nivel de bytecode, las llamadas a este tipo de métodos desde otros lenguajes tipados dinámicamente ya no se apoyarán en la reflection de Java, sino en esta nueva instrucción.

Las ventajas de esto es que se mejora el rendimiento a la misma vez que hace que la JVM sea independiente del lenguaje, por lo que aumenta la interoperabilidad entre componentes creados en otros lenguajes y los programas escritos en Java.

JLayerPane

Componente similar a uno proporcionado en el proyecto JXLayer, que sirve para añadir efectos a componentes Swing. JLayerPane permite decorar los componentes gráficos de Swing y añadir eventos a los mismos sin modificar el código de esos componentes.

JLayerPane (Foto: sellmic)

Via: sellmic

Comentarios

Entradas populares de este blog

Soluciones Alchemy Classic 389 elementos

Hace algún tiempo salió una actualización del Juego Alchemy Classic en la que aparecían más elementos (389 en lugar de 238). Aparte de añadir elementos mejoran algunas traducciones en castellano y mejoran la interfaz, aunque todavía hay algún error en algunos nombres de elementos. Aquí os dejo las soluciones para los que estén atascados y no puedan dormir por las noches: Sustancia primaria Aire=Elemento primario  Fuego=Elemento primario  Agua=Elemento primario  Tierra=Sustancia Primaria Arena=Piedra + Aire Piedra=Tierra + Fuego Arcilla=Arena + Pantano Caliza=Tierra + Amonitas Carbono=Fuego + Madera Cloro=Fuego + Sal + Electricidad CO2(Dióxido de Carbono)=Ceniza + Ácido nítrico Electricidad=Relámpago+ Metales Gas natural= Yacimiento de gas + Pozo Helio=Refinería de gas + Gas Natural Hidrógeno=Electricidad + Agua Hielo=Frío + Agua Imán=Piedra + Metales Metano=Deshechos Vegetales + Pantano Oxígeno=Electricidad + Agua Petróleo=Unidad

JAXB: Leer y escribir ficheros XML

Muchas veces en nuestras aplicaciones debemos manejar documentos XML ( Extensible Markup Language ). Este lenguaje se ha convertido en un estándar para intercambio de datos entre programas y aplicaciones a través de Internet. En un esquema XML (o  XSD ) podemos definir los elementos que pueden aparecer en un documento XML así como las relaciones entre los mismos. JAXB ( Java Architecture for XML Binding ) es un estándar Java para transformar un esquema XML (o  XSD ) en una representación a objetos java. Mediante la API de JAXB podemos mapear un objeto Java a un documento XML ( "marshall" ) y el proceso contrario, es decir, a partir de un esquema XML crear su conjunto de objeto Java asociado ( "unmarshall" ). JAXB Resumiendo lo que nos proporciona JAXB es: Generación de objetos Java a partir de un XSD a través de un compilador Proporciona capacidades de marshall/unmarshall (escribir fichero XML desde java y al contrario) Integración con Maven a través de xj

Matemáticas y cine.

El otro día estaba viendo por la televisión una película llamada 21 blackjack . En una escena de la película el profesor de matemáticas ( Kevin Spacey ) le presenta a uno de sus alumnos la siguiente situación: se encuentra en un concurso en la que debe escoger entre tres puertas (1,2 y 3). En dos de ellas hay una cabra, sin embargo en una de las 3 hay un flamante coche nuevo. El alumno responde que quiere abrir la puerta. El presentador, conocedor de lo que hay detrás de cada puerta decide abrir otra puerta diferente mostrando detrás de ella una cabra. El profesor se dirige al alumno y le pregunta, ¿cambiarías la puerta o te quedarías con la puerta que tienes? Muchos de nosotros cambiaríamos de puerta pensando que es una treta del presentador para engañarnos. ¿Cual elegiríais vosotros? Al comienzo tenemos 1/3 de probabilidades de acertar la puerta donde está el coche. Una vez que el presentador abre la puerta con una cabra, la mayoría de gente piensa que hay la misma probabilidad de