martes, septiembre 01, 2009

Novedades que tendrá el compilador en el JDK 7

Joseph Darcy nos cuenta las novedades que tendrá el compilador en el JDK 7. En general son cambios menores debatidos en los foros, que incluyen varias comodidades en la sintaxis del lenguaje.

Las novedades del JDK 7 serán:

  • Switch con objetos de tipo String
  • Gestión automática de recursos
  • Mejoras en la inferencia de tipos para la creación de Generics
  • Invocación de métodos con varargs simplificada
  • Mejoras en los literales numéricos
  • Soporte en el lenguaje para Collections
  • Soporte en el lenguaje para JSR 292

Veamos en detalle estas características.

Switch con objetos de tipo String

Será posible utilizar el operador switch con objetos de tipo String. De esta manera se evitan los potenciales "if-then-else". Entonces, esta nueva funcionalidad nos permitiría:


String s = ...
switch(s) {
case "quux":
procesarQuux(s);
// y seguir...

case "foo":
case "bar":
procesarFooBar(s);
break;

case "Gaz":
procesarGaz(s);
// y seguir...

default:
procesarPredeterminado(s);
break;
}

Gestión automática de recursos

Un "recurso" es un objeto que tiene que cerrarse manualmente, como ser java.io.InputStream, OutputStream, Reader, Writer, Formatter;
java.nio.Channel;java.net.socket; java.sql.Connection, Statement, ResultSet entre otros. Estos recursos se suelen abrir en un bloque try y cerrar en un finally.

La gestión automática de rcursos es una forma especial del operador try en donde se declaran uno o más recursos. El alcance de estos recursos está limitado al bloque. Cuando el bloque termina, sea de forma normal o abrupta, todos los recursos declarados se cierran automáticamente.

La principal ventaja es que se elimina la necesidad del cierre manual, y los posibles errores que eso provoca. Además, se "evita" la segunda excepción (la del close()), dejando siempre la excepción del bloque que suele ser más interesante.

Un ejemplo de uso sería:


static String readFirstLineFromFile2(String path) throws IOException {

try (BufferedReader br = new BufferedReader(new FileReader(path)) {

return br.readLine();

}
}

Como vemos, el bloque try() declara un recurso, el luego es utilizado dentro del bloque. Al finalizar, se cerrará automáticamente. También es posible declarar más de un recurso:


try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest)) {

byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}

Mejoras en la inferencia de tipos para la creación de Generics

Se incluirá la posiblidad de inferir los tipos para la creación de instancias usando Generics. En los casos que los tipos parametrizados sean obvios según el contexto, esta parametrización puede omitirse en el constructor y reemplazarse por un conjunto vacio: <>.

Por ejemplo, la siguiente línea:

     Map> anagrams = new HashMap>();

puede ser reemplazada por:

     Map anagrams = new HashMap<>();

Mejoras en los literales numéricos

Así como podemos declarar literales numéricos decimales, octales y hexadecimales, ahora también podremos declarar literales binarios. Esto resulta muy útil en ciertos ámbitos. Para esto se utiliza el prefijo 0b, el cual además es el mismo que usan los compiladores C/C++, Ruby y Python. Por ejemplo:


// Un literal 'byte' de 8-bits
byte aByte = (byte)0b00100001;

// Un literal 'short' de 16-bits
short aShort = (short)0b1010000101000101;

// Varios literales 'int' de 32-bit 'int'
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;

Estas variables luego se usan normalmente; por ejemplo:


class Foo {
public static void main(String[] args) {
System.out.println("El valor decimal de 10100001 es " + 0b10100001);
}

Por otro lado, se agregó la posiblidad de usar un guión bajo (_) como separador de números, para facilitar la lectura de los mismos. De esta manera, el compilador ignorará al caracter "_" cuando sea utilizado en literales numéricos. Por ejemplo:


int numeroDeTelefono = 555_555_1212;
long tarjetaDeCredito = 1234_5678_9012_3456L;
long legajo = 999_99_9999L;
float cantidadDeDinero = 12_345_132.12;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xFFEC_DE5E;
long maxLong = 0x7fff_ffff_ffff_ffffL;
long bytes = 0b11010010_01101001_10010100_10010010;

Soporte en el lenguaje para Collections

Se agrega el soporte al lenguaje para tratar a las Collection como si fueran Arrays.

Por ejemplo, se podrá escribir lo siguiente para declarar un List inmutable:


final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9];

También será posible acceder a las listas y maps usando una sintaxis de arrays:


public class Main {
public static void main(String[] arguments) {
List lista = Arrays.asList(new String[] {"a", "b", "c"});
String primerElemento = lista[0]

Map m1 = new HashMap(4);
m1[Integer.valueOf(1)] = "One";
}

Soporte en el lenguaje para JSR 292

Este cambio de bajo nivel realizará modificaciones menores en el lenguaje Java para que se más simple trabajar con algunas características de la JVM. Esto va a permitir que el código Java pueda interoperar y/o implementar librerías en otros lenguajes. Es decir, se logrará una mayor integración entre Java y código en otros lenguajes. Para ver más detalles leer la propuesta del soporte para JSR 292.

Fuente: DosIdeas