Inferencia de tipo de variable local de Java 10

Este artículo es parte de una serie: • Java 10 LocalVariable Type-Inference (artículo actual) • Java 10 Performance Mejoras

• Nuevas funciones de Java 10

1. Información general

Una de las mejoras más visibles en JDK 10 es la inferencia de tipos de variables locales con inicializadores.

Este tutorial proporciona los detalles de esta función con ejemplos.

2. Introducción

Hasta Java 9, teníamos que mencionar el tipo de variable local explícitamente y asegurarnos de que fuera compatible con el inicializador utilizado para inicializarla:

String message = "Good bye, Java 9";

En Java 10, así es como podríamos declarar una variable local:

@Test public void whenVarInitWithString_thenGetStringTypeVar() { var message = "Hello, Java 10"; assertTrue(message instanceof String); }

No proporcionamos el tipo de datos del mensaje . En su lugar, marcamos el mensaje como var , y el compilador infiere el tipo de mensaje del tipo de inicializador presente en el lado derecho.

En el ejemplo anterior, el tipo de mensaje sería Cadena .

Tenga en cuenta que esta función solo está disponible para variables locales con el inicializador. No se puede utilizar para variables miembro, parámetros de método, tipos de retorno, etc. El inicializador es necesario, ya que sin el compilador no podrá inferir el tipo.

Esta mejora ayuda a reducir el código repetitivo; por ejemplo:

Map map = new HashMap();

Esto ahora se puede reescribir como:

var idToNameMap = new HashMap();

Esto también ayuda a centrarse en el nombre de la variable más que en el tipo de variable.

Otra cosa a tener en cuenta es que var no es una palabra clave ; esto asegura la compatibilidad con versiones anteriores para los programas que usan var say, como una función o nombre de variable. var es un nombre de tipo reservado, como int .

Finalmente, tenga en cuenta que no hay una sobrecarga de tiempo de ejecución al usar var ni hace que Java sea un lenguaje escrito dinámicamente. El tipo de variable aún se infiere en tiempo de compilación y no se puede cambiar más adelante.

3. Uso ilegal de var

Como se mencionó anteriormente, var no funcionará sin el inicializador:

var n; // error: cannot use 'var' on variable without initializer

Tampoco funcionaría si se inicializara con nulo :

var emptyList = null; // error: variable initializer is 'null'

No funcionará para variables no locales:

public var = "hello"; // error: 'var' is not allowed here

La expresión lambda necesita un tipo de destino explícito y, por lo tanto , no se puede usar var :

var p = (String s) -> s.length() > 10; // error: lambda expression needs an explicit target-type

Lo mismo ocurre con el inicializador de matriz:

var arr = { 1, 2, 3 }; // error: array initializer needs an explicit target-type

4. Directrices para el uso de var

Hay situaciones en las que var se puede usar legalmente, pero puede que no sea una buena idea hacerlo.

Por ejemplo, en situaciones en las que el código podría volverse menos legible:

var result = obj.prcoess();

Aquí, aunque es un uso legal de var , se vuelve difícil entender el tipo devuelto por el proceso () haciendo que el código sea menos legible.

java.net tiene un artículo dedicado a Pautas de estilo para la inferencia de tipos de variables locales en Java, que habla sobre cómo debemos usar el juicio al usar esta función.

Otra situación en la que es mejor evitar var es en flujos con una tubería larga:

var x = emp.getProjects.stream() .findFirst() .map(String::length) .orElse(0);

El uso de var también puede dar resultados inesperados.

Por ejemplo, si lo usamos con el operador de diamante introducido en Java 7:

var empList = new ArrayList();

El tipo de empList será ArrayList y no List . Si queremos que sea ArrayList , tendremos que ser explícitos:

var empList = new ArrayList();

El uso de var con tipos no identificables podría provocar un error inesperado.

Por ejemplo, si usamos var con la instancia de clase anónima:

@Test public void whenVarInitWithAnonymous_thenGetAnonymousType() { var obj = new Object() {}; assertFalse(obj.getClass().equals(Object.class)); }

Ahora, si intentamos asignar otro Objeto a obj , obtendríamos un error de compilación:

obj = new Object(); // error: Object cannot be converted to 

Esto se debe a que el tipo inferido de obj no es Object .

5. Conclusión

En este artículo, vimos la nueva función de inferencia de tipo de variable local de Java 10 con ejemplos.

Como de costumbre, los fragmentos de código se pueden encontrar en GitHub.

Siguiente » Mejoras de rendimiento de Java 10