Java 7, ¿qué nos trae?

Vale, lo sé, algo tarde porque salió en julio de este año… pero más vale tarde que nunca, ¿no?

El hecho, es que se ha lanzado una nueva versión de este tan afamado lenguaje. Oracle ha preparado su SDK y, según Mark Reinhold (Arquitecto Jefe de Java en Oracle), se han corregido 9494 errores, se han incluido 1966 mejoras, 9018 cambios, 4 JSRs y 147 builds hasta llegar a esta versión, que ha tardado unos 4 años en ver la luz.

Las mejoras que implementa Java 7 son las siguientes.

Máquina Virtual

Se agrega el requisito señalado en el JSR 292, que da mejor soporte a nivel de JVM para la implementación mejorada de lenguajes scripting sobre la JVM.

Un mejor recolector de basura (Garbage Collector), G1. El recolector de basura es ese sistema que se encarga de liberar la memoria de los objetos que ya no se están usando. El hecho, es que para llevar a cabo esta tarea, la JVM dejaba pausada toda su actividad para poder realizar la tarea sin problemas de concurrencia.

Con la puesta en producción de G1, los tiempos de pausa son más cortos. Se basa en la teoría de que, ordenar el espacio en memoria mientras los niños juegan, como un reemplazo a la marca de recolección de basura paralela y concurrente. Se divide la sala de estar en cuadrados, y se van turnando para cada juego, muchos de los cuadros contienen juguetes que ya no se usan y pueden ser quitados sin peligro. El nuevo colector, por tanto, puede trabajar de forma más predictiva.

Otra de las mejoras, es que se comprimen los punteros a memoria de 64 bits en 32 bits con lo que se gana mayor rendimiento.

Lenguaje

Se agregan características del lenguaje como el uso de String en switch, con lo que ya sería posible hacer códigos como este:

String hola = "Hola";
switch (hola) {
    case "hola": // no coincide
        break;
    case "Hola": // si coincide
        break;
    default:
}

Mejorado el tipo de inferencia para la instanciación genérica. Hasta ahora cuando se creaba un objeto, había que dar todos los tipos con los que se había creado el objeto. Ahora, esto no es necesario. Un ejemplo:

// Java 6
Map<String, List<String>> anagrama = new HashMap<String, List<String>>();
 
// Java 7
Map<String, List<String>> anagrama = new HashMap<>();

Gestión automática de recursos. Es posible ahora definir recursos dentro de la cláusula try para que el alcance de estos recursos se quede limitado a esta cláusula. La forma sería:

try (FileOutputStream fos = new FileOutputStream(path)) {
    // código para procesar fos
} catch(Exception ex) {
    System.out.println(ex);
}

Se amplian los formatos numéricos, haciéndose posible escribir cosas como:

int n = 0b10000000;
System.out.println(n);  // imprime 128
 
int n2 =  121_31_23_232;   // literal entero con subrayados
int n3 =  0xff_dd;   // liberal hexadecimal con subrayados
System.out.println(n2);
System.out.println(n3);

Se agrega también un sistema multi-catch, que permite definir varios tipos de objetos en una sola cláusula catch:

try {
    int v = Integer.parseInt(num);
    int result = 100 / v;
    System.out.println(result);
} catch(NumberFormatException | ArithmeticException ex ) {
    System.out.println("Not a valid number or zero");
}

Además, se hacen posibles códigos de lanzamiento de excepciones como este:

class Ex1 extends Exception { }
class Ex2 extends Exception { }
 
public class RethrowException {
    public void m1(int v)  throws Ex1 , Ex2 {
        try {
            if (v < ) {
                throw new Ex1();
            } 
            else
               if ( v > 100 ) {
                   throw new Ex2();
               }
            // process 
        } 
        catch (Exception ex) {
            throw ex;   // excepción no reportada java.lang.Exception
        }
    }
}

Por último, en esta sección, cabe destacar que, cuando un programador intenta invocar un método con parámetros variable, el compilador genera una aviso de operación insegura, este aviso, en JDK 7 ha sido movido del sitio de la llamada a la declaración del método.

Núcleo

Se actualiza la arquitectura del class-loader (cargador de clases). Elimina interbloqueos en topologías no jerárquicas. Ver más (en inglés).

Se agrega un método en URL ClassLoader, que permite cerrar recursos subyacentes, tales como archivos abiertos, mantenidos por URL ClassLoader. Ver más (en inglés).

También se agregan actualizaciones en las colecciones (Collections) y concurrencia. Un ligero marco de trabajo (framework) para fork/join, barreras de sincronización más flexibles y reutilizables, colas de transferencia, colas de listas doblemente enlazadas concurrentes y generadores de números pseudo-aleatorios en hilos locales. Ver más (en inglés).

Internacionalización

Actualización a la versión de Unicode 6.0, que:

  • agrega 2088 caracteres incluyendo 1000 símbolos adicionales, el símbolo de la moneda india oficial, 222 ideogramas de China, Taiwan y Japón y 630 caracteres adicionales de soporte para lengua africana, incluyendo extensiones de Tifinagh, Etiopía y Bamum.
  • agrega nuevas propiedades y ficheros de datos, como el fichero EmojiSources.txt, que mapea los símbolos emoji a su japonés original, dos propiedades provisionales de scripts del índico: IndicMatraCategory y IndicSylabicCategory; y scripts provisionales para uso en segmentación, expresiones regulares y detección de spoof.
  • corrige propiedades de caracteres para caracteres existentes.
  • etc.

Mejoras en Locale (java.util.Locale) para soportar el IETF BCP 47 (etiquetas para detectar idiomas) y el UTR 35 (lenguaje de marcado para datos localizados).

Separación de la localización del usuario, de la localización de la interfaz de usuario. Actualiza el manejador de locales para separar el formateado de locales de la interfaz del usuario de las locales de idioma.

Entrada/Salida y Red

Nueva API para E/S que permite acceso al sistema de ficheros, operaciones E/S asíncronas escalables, enlace con canal de socket y configuración, y datagramas multicast. Ver más. Además, esta API tendrá acceso para ficheros zip/jar.

Soporte para el protocolo SCTP (Stream Control Transmission Protocol, Protocolo de Transmisión de Control de Flujo) en Solaris, así como el SDP (Sockets Direct Protocol, Protocolo Directo a Sockets) para Solaris y Linux, y la posibilidad de usar la pila IPv6 nativa de Windows Vista.

Agregado soporte para TLS 1.2, según el RFC 5246.

Seguridad y Criptografía

Se agrega los algoritmos de Criptografía de Curva-Elíptica (ECC, Eliptic-curve criptography), así que todas las aplicaciones Java podrán usar ECC con la JVM estándar (out-of-the-box).

Base de Datos

Actualización de JDBC a la versión 4.1, y Rowset a la versión 1.1. Básicamente, incluye las nuevas características del lenguaje para hacer más óptimo y manejable el sistema JDBC.

Cliente

Un nuevo sistema de acceso a gráficos basado en la extensión XRender de X11, el cual proporciona acceso a mucha más funcionalidad de los GPUs, para Java2D.

Creada unas nuevas funcionalidades para API gráfica, que permitan el uso de Shapes (curvas) y Opacity (opacidad), en java.awt.

Nuevo look-and-feel para Swing llamado Nimbus. Se proclama como la siguiente generación en look-and-feel multi-plataforma para Swing. Una imagen de cómo es:

Nueva componente JLayer. Se agrega por defecto la componente decoradora JXLayer de SwingLabs. Aquí un ejemplo de cómo implementarla. El ejemplo permite cosas como esta:

Se elimina el antiguo (y propietario) sintetizador, en favor de Gervill, un sintetizador creado como propuesta del Audio Synthesis Engine Project.

Web

Actualizada la pila XML a las versiones más recientes de JAXP 1.4, JAXB 2.2a y JAX-WS 2.2.

Administración

Mejorado MBeans para informar la carga reciente de la CPU en general (del sistema completo), la carga CPU de los procesos de la JVM y enviar notificaciones JMX cuando ocurran eventos del recolector de basura (GC), esta característica fue incluída como mejora del Agente JMX, pero ha sido eliminada debido a la falta de tiempo.

Otras cosas por venir… JDK 8

Hay otras muchas cosas que se dejan para la siguiente versión, cosas como la modularización, el uso de anotaciones en los tipos, soporte del lenguaje para colecciones, closures… y otras muchas cosas que se piensen a partir de este momento, hasta que se plantee la liberación del JDK 8.

Conclusiones

Veo que el lenguaje Java, con estas propuestas y las que están por venir, se va acoplando cada vez más a la moda que van imponiendo sistemas como Groovy, Ruby, Python y otros lenguajes de scripting, agregando más elementos nativos, ganando en rendimiento y disminuyendo la necesidad de escribir tanto código. No obstante, no a todo el mundo le gusta esta línea, ya que deja al lenguaje demasiado dependiente de las APIs de cara al uso de elementos nativos como las estructuras de control… habrá que ver cómo sigue evolucionando.