1. Azúcar sintáctico

A los programadores les encanta cuando se puede escribir código complejo o lógica en un par de líneas, lo que hace que el código sea compacto y legible. Y los creadores de lenguajes de programación a veces ayudan con esto.

Una función de lenguaje ingenioso que le permite tomar un atajo (escribir menos código) se llama azúcar sintáctico . Pero, para ser honesto, hay muy poco en Java.

Los creadores de Java hicieron todo lo posible para eliminar cualquier redundancia en Java. Si C++ te permite hacer algo de 20 maneras, Java te permite hacerlo de una sola manera.

Pero ni a los programadores de Java ni a los creadores de Java les gustó la falta de libertad. Y a veces el azúcar hace la vida más fácil para la gente común como tú y como yo.

Por cierto, ya te has encontrado con algo de azúcar sintáctico: autoboxing y unboxing . Comparemos:

código largo Código compacto
Integer a = new Integer(5);
int b = a.intValue();
Integer a = 5;
int b = a;
int b = 5;
Integer c = new Integer(b);
int b = 5;
Integer c = b;
Integer a = new Integer(1);
int b = 1;
if (a.intValue() == b)
{
   ...
}
Integer a = 1;
int b = 1;
if (a == b)
{
   ...
}

En lugar del código largo como el de la izquierda, puede escribir el código más compacto de la derecha. Y el compilador inteligente de Java generará la versión detallada del código en función de la versión corta del código. Esto es exactamente lo que es el azúcar sintáctico.


2. Inferencia del tipo de una variable: la varpalabra clave

En Java 11, el compilador se volvió aún más inteligente y ahora puede determinar el tipo de una variable declarada en función del tipo de valor que se le asigna . En código, se ve así:

var name = value;

Donde namees el nombre de una nueva variable, valor es su valor inicial y vares una palabra clave utilizada para declarar la variable. El tipo de la variable de nombre será el mismo que el tipo del valor que se le asigne.

Ejemplos:

Cómo vemos el código Lo que ve el compilador
var i = 1;
int i = 1;
var s = "Hello";
String s = "Hello";
var console = new Scanner(System.in);
Scanner console = new Scanner(System.in);
var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
var data = new int[]{1, 2, 3};
int[] data = new int[]{1, 2, 3};

El propio compilador determina, o infiere, el tipo de variable en función del valor que se le asigna.

Los programadores debatieron acaloradamente sobre si agregar tal característica al lenguaje. Mucha gente temía que varse abusara de eso y que, como resultado, la legibilidad del código se resintiera.

Hay una pizca de verdad en esto, por lo que es mejor usarlo varcuando aumente la legibilidad del código. Por ejemplo, estos en dos casos:

Caso 1: Mirando el valor asignado a la variable, el tipo de variable es inmediatamente claro

Código Explicación
var stream = url.getInputStream();
La variable es unaInputStream
var name = person.getFullName();
la variable es unaString

En estos casos, no debe usar var. Bueno, ¿cuál es el tipo de variable?

Código Explicación
var result = task.execute();
Es difícil determinar el tipo de variable.
var status = person.getStatus();
Es difícil determinar el tipo de variable.

Caso 2: El tipo de variable no es importante para entender el código

El código a menudo no necesita llamar a métodos en una variable, por ejemplo, cuando una variable simplemente se usa para almacenar algo temporalmente. En este caso, usar vardefinitivamente no reduce la legibilidad del código:

código largo Código compacto
var data = stream.getMetaData();
storage.save(data)
Obtuvimos metadatos de la streamtransmisión y los guardamos en el storagerepositorio. El datatipo específico de la variable no es importante.

la media dorada

Ahora daré tres formas de escribir el mismo código. Usar varsería la mejor opción.

Código Nota
dest.writeHeaderInfo(src.getFileMetaInfo());
demasiado compacto
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Solo bien
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
demasiado detallado

Al pasar de la versión de 1 línea a la versión de 2 líneas, hicimos que el código fuera un poco más legible usando un nombre de variable ( headerInfo). Ahora está claro que el método devuelve no solo metainformación, sino también información de encabezado.

La tercera versión es demasiado detallada. El hecho de que headerInfoes a FileMetaInfoya está bastante claro a partir del getFileMetaInfo()método. El propósito de la metainformación es mucho más interesante.



3. Omitiendo el tipo con el operador de diamante:<>

Incluso antes de que varapareciera el operador, hubo intentos de enseñar al compilador cómo inferir los tipos de colección. Estarás de acuerdo en que esta notación parece un poco redundante:

ArrayList<String> list = new ArrayList<String>();

A partir de la séptima versión de Java, al escribir un tipo de colección, podía omitir el tipo de los elementos de la colección si se especificaba al declarar una variable. En otras palabras, el código anterior se puede escribir en una forma ligeramente abreviada:

ArrayList<String> list = new ArrayList<>();

Como puede ver, ya no necesita escribir String por segunda vez. No tan genial como con el operador var, pero parecía un progreso en ese momento.

Los corchetes angulares vacíos en el tipo de colección se denominaron operador de diamante , ya que los dos corchetes angulares se asemejan vagamente a un diamante.

No es deseable utilizar la varpalabra clave y el operador de diamantes al mismo tiempo :

var list = new ArrayList<>();

No hay ninguna información sobre el tipo de elementos almacenados en la colección, y el tipo de colección será ArrayList < Object >.



4. Llaves dobles

¿Recuerdas la inicialización rápida de matrices?

Acabamos de enumerar valores entre llaves, así:

Ejemplos
int[] data = new int[] {1, 2, 3, 4, 5, 6, 7};
int[] data = {1, 2, 3, 4, 5, 6, 7};

A los creadores de Java les encantó la idea de usar llaves para simplificar la escritura de elementos de una matriz. Pero, ¿y las colecciones?

Los creadores de Java también tenían suficiente pensamiento creativo para las colecciones, lo que les permitió usar un truco con llaves dobles.

Con azucar Sin azúcar
var list = new ArrayList<String>()
{{
   add("Hello");
   add("How's");
   add("Life?");
}};
var list = new ArrayList<String>();

list.add("Hello");
list.add("How's");
list.add("Life?");

Si el compilador encuentra código como en el ejemplo de la izquierda, lo convierte al código de la derecha.

El código no se vuelve mucho más compacto. Los ahorros aquí son bastante insignificantes: no tienes que escribir listcada vez. Esto puede ser útil si el nombre de la variable es muy largo.

Pero si te encuentras con un código como este en un proyecto, no te sorprendas 🙂