1. Açúcar sintático

Os programadores adoram quando algum código ou lógica complexa pode ser escrito em algumas linhas, tornando o código compacto e legível. E os criadores de linguagens de programação às vezes ajudam nisso.

Um recurso de linguagem inteligente que permite pegar um atalho (escrever menos código) é chamado de açúcar sintático . Mas, para ser honesto, há muito pouco disso em Java.

Os criadores de Java fizeram tudo o que puderam para eliminar qualquer redundância em Java. Se C++ permite que você faça algo de 20 maneiras, então Java permite que você faça apenas uma maneira.

Mas nem os programadores de Java nem os criadores de Java gostaram da falta de liberdade. E às vezes o açúcar torna a vida mais fácil para pessoas comuns como você e eu.

A propósito, você já encontrou algum açúcar sintático: autoboxing e unboxing . Vamos comparar:

código longo 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)
{
   ...
}

Em vez do código longo como à esquerda, você pode escrever o código mais compacto à direita. E o compilador Java inteligente gerará a versão detalhada do código com base na versão curta do código. Isso é exatamente o que o açúcar sintático é.


2. Inferência do tipo de uma variável: a varpalavra-chave

No Java 11, o compilador ficou ainda mais inteligente e agora pode determinar o tipo de uma variável declarada com base no tipo do valor atribuído a ela . Em código, fica assim:

var name = value;

Onde nameé o nome de uma nova variável, value é seu valor inicial e varé uma palavra-chave usada para declarar a variável. O tipo da variável name será o mesmo que o tipo do valor atribuído a ela.

Exemplos:

Como vemos o código O que o compilador vê
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};

O próprio compilador determina, ou infere, o tipo da variável com base no valor atribuído a ela.

Os programadores debateram acaloradamente se deveriam adicionar tal recurso à linguagem. Muitas pessoas temiam que isso varfosse abusado e que a legibilidade do código fosse prejudicada como resultado.

Há um grão de verdade nisso, então é melhor usar varonde aumenta a legibilidade do código. Por exemplo, estes em dois casos:

Caso 1: Olhando para o valor atribuído à variável, o tipo da variável é imediatamente claro

Código Explicação
var stream = url.getInputStream();
A variável é umInputStream
var name = person.getFullName();
A variável é umString

Nesses casos, você não deve usar var. Bem, qual é o tipo da variável?

Código Explicação
var result = task.execute();
É difícil determinar o tipo da variável
var status = person.getStatus();
É difícil determinar o tipo da variável

Caso 2: O tipo da variável não é importante para entender o código

O código geralmente não precisa chamar métodos em uma variável, por exemplo, quando uma variável é simplesmente usada para armazenar algo temporariamente. Nesse caso, usar vardefinitivamente não reduz a legibilidade do código:

código longo Código compacto
var data = stream.getMetaData();
storage.save(data)
Obtivemos os metadados do streamstream e os salvamos no storagerepositório. O datatipo específico da variável não é importante.

o meio dourado

Agora darei três maneiras de escrever o mesmo código. Usar varseria a melhor opção.

Código Observação
dest.writeHeaderInfo(src.getFileMetaInfo());
Muito compacto
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Na medida
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Detalhado demais

Passando da versão com 1 linha para a versão com 2 linhas, tornamos o código um pouco mais legível usando um nome de variável ( headerInfo). Agora está claro que o método retorna não apenas metainformações, mas também informações de cabeçalho.

A terceira versão é excessivamente detalhada. O fato de headerInfoser a FileMetaInfojá está bastante claro no getFileMetaInfo()método. O propósito da meta informação é muito mais interessante.



3. Omitindo o tipo com o operador diamante:<>

Mesmo antes do varaparecimento do operador, houve tentativas de ensinar o compilador a inferir tipos de coleção. Você concordará que esta notação parece um pouco redundante:

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

A partir da sétima versão do Java, ao escrever um tipo de coleção, você pode omitir o tipo dos elementos da coleção se for especificado ao declarar uma variável. Em outras palavras, o código acima pode ser escrito de uma forma ligeiramente abreviada:

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

Como você pode ver, você não precisa mais escrever String uma segunda vez. Não tão legal quanto com o operador var, mas parecia um progresso na época.

Os colchetes angulares vazios no tipo de coleção eram chamados de operador diamante , pois os dois colchetes angulares se assemelham vagamente a um diamante.

É indesejável usar a varpalavra-chave e o operador diamante ao mesmo tempo :

var list = new ArrayList<>();

Não há nenhuma informação sobre o tipo dos elementos armazenados na coleção, e o tipo de coleção será ArrayList < Object >.



4. Chaves duplas

Lembra da inicialização rápida do array?

Acabamos de listar os valores entre chaves, assim:

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

Os criadores de Java adoraram a ideia de usar chaves para simplificar a escrita de elementos de um array. Mas e as coleções?

Os criadores de Java também tinham pensamento criativo suficiente para coleções, permitindo-lhes usar um truque com chaves duplas.

Com açucar Sem açú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?");

Se o compilador encontrar um código como no exemplo à esquerda, ele o converterá no código à direita.

O código não se torna muito mais compacto. A economia aqui é bastante insignificante: você não precisa escrever listtodas as vezes. Isso pode ser útil se o nome da variável for muito longo.

Mas se você encontrar um código como este em um projeto, não se surpreenda 🙂