Inferência de tipo variável do Java 10 Local
1. Visão geral
Um dos aprimoramentos mais visíveis no JDK 10 é a inferência de tipo de variáveis locais com inicializadores.
Este tutorial fornece os detalhes desse recurso com exemplos.
2. Introdução
Até o Java 9, tínhamos que mencionar explicitamente o tipo da variável local e garantir que ela fosse compatível com o inicializador usado para inicializá-la:
String message = "Good bye, Java 9";
No Java 10, é assim que podemos declarar uma variável local:
@Test
public void whenVarInitWithString_thenGetStringTypeVar() {
var message = "Hello, Java 10";
assertTrue(message instanceof String);
}
*Nós não fornecemos o tipo de dados de _message_. Em vez disso, marcamos __ a mensagem __ como um _var_ e o compilador infere o tipo de __mensage __do tipo do inicializador presente no lado direito.*
No exemplo acima, o tipo de mensagem seria String.
-
Observe que esse recurso está disponível apenas para variáveis locais com o inicializador. *Ele não pode ser usado para variáveis-membro, parâmetros de método, tipos de retorno, etc. - o inicializador é necessário, pois sem o qual o compilador não poderá inferir o tipo.
Esse aprimoramento ajuda a reduzir o código padrão; por exemplo:
Map<Integer, String> map = new HashMap<>();
Agora, isso pode ser reescrito como:
var idToNameMap = new HashMap<Integer, String>();
Isso também ajuda a focar no nome da variável e não no tipo de variável.
Outro aspecto a ser observado é que* var não é uma palavra-chave *- isso garante compatibilidade com versões anteriores de programas que usam var say, como uma função ou nome de variável. var é um nome de tipo reservado, assim como int.
Por fim, observe que* não há sobrecarga de tempo de execução no uso de var , nem faz do Java uma linguagem de tipo dinâmico. *O tipo da variável ainda é inferido em tempo de compilação e não pode ser alterado posteriormente.
3. Uso ilegal de var
Como mencionado anteriormente, var não funcionará sem o inicializador:
var n;//error: cannot use 'var' on variable without initializer
Nem funcionaria se inicializado com null:
var emptyList = null;//error: variable initializer is 'null'
Não funcionará para variáveis não locais:
public var = "hello";//error: 'var' is not allowed here
A expressão lambda precisa de um tipo de destino explícito e, portanto, var não pode ser usado:
var p = (String s) -> s.length() > 10;//error: lambda expression needs an explicit target-type
O mesmo ocorre com o inicializador de array:
var arr = { 1, 2, 3 };//error: array initializer needs an explicit target-type
===* 4. Diretrizes para usar var *
Há situações em que var podem ser usadas legalmente, mas pode não ser uma boa ideia fazê-lo.
Por exemplo, em situações em que o código pode se tornar menos legível:
var result = obj.prcoess();
Aqui, embora seja um uso legal de var, fica difícil entender o tipo retornado pelo process () tornando o código menos legível.
java.net.la possui um artigo dedicado em https://openjdk.java.net/projects/amber/LVTIstyle.html[Diretrizes de estilo para inferência local de tipo variável em Java, que fala sobre como devemos julgar enquanto estiver usando esse recurso.
Outra situação em que é melhor evitar var está em fluxos com pipeline longo:
var x = emp.getProjects.stream()
.findFirst()
.map(String::length)
.orElse(0);
O uso de var também pode fornecer resultados inesperados.
Por exemplo, se o usarmos com o operador diamond introduzido no Java 7:
var empList = new ArrayList<>();
O tipo de empList será ArrayList <Object> e não _List <Object> _. Se queremos que seja _ArrayList <Employee> _, teremos que ser explícitos:
var empList = new ArrayList<Employee>();
*O uso de __var __ com tipos não denotáveis pode causar erros inesperados.*
Por exemplo, se usarmos var com a instância da classe anônima:
@Test
public void whenVarInitWithAnonymous_thenGetAnonymousType() {
var obj = new Object() {};
assertFalse(obj.getClass().equals(Object.class));
}
Agora, se tentarmos atribuir outro Object a obj, obteremos um erro de compilação:
obj = new Object();//error: Object cannot be converted to <anonymous Object>
Isso ocorre porque o tipo inferido de obj não é Object.
5. Conclusão
Neste artigo, vimos o novo recurso de inferência de tipo de variável local Java 10 com exemplos.
Como sempre, trechos de código podem ser encontrados over no GitHub.