Java 10 LocalVariable Type-Inference

Questo articolo fa parte di una serie: • Java 10 LocalVariable Type-Inference (articolo corrente) • Miglioramenti delle prestazioni di Java 10

• Nuove funzionalità di Java 10

1. Panoramica

Uno dei miglioramenti più visibili in JDK 10 è l'inferenza del tipo di variabili locali con inizializzatori.

Questo tutorial fornisce i dettagli di questa funzione con esempi.

2. Introduzione

Fino a Java 9, dovevamo menzionare esplicitamente il tipo di variabile locale e assicurarci che fosse compatibile con l'inizializzatore utilizzato per inizializzarlo:

String message = "Good bye, Java 9";

In Java 10, è così che potremmo dichiarare una variabile locale:

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

Non forniamo il tipo di dati del messaggio . Contrassegniamo invece il messaggio come una variabile e il compilatore deduce il tipo di messaggio dal tipo di inizializzatore presente sul lato destro.

Nell'esempio precedente, il tipo di messaggio sarebbe String .

Notare che questa funzione è disponibile solo per le variabili locali con l'inizializzatore. Non può essere utilizzato per variabili membro, parametri di metodo, tipi restituiti, ecc. L'inizializzatore è richiesto poiché senza il quale il compilatore non sarà in grado di dedurre il tipo.

Questo miglioramento aiuta a ridurre il codice boilerplate; per esempio:

Map map = new HashMap();

Questo può ora essere riscritto come:

var idToNameMap = new HashMap();

Questo aiuta anche a concentrarsi sul nome della variabile piuttosto che sul tipo di variabile.

Un'altra cosa da notare è che var non è una parola chiave : ciò garantisce la compatibilità con le versioni precedenti per i programmi che utilizzano var say, come nome di una funzione o di una variabile. var è un nome di tipo riservato, proprio come int .

Infine, si noti che non vi è alcun sovraccarico di runtime nell'uso di var né rende Java un linguaggio tipizzato dinamicamente. Il tipo di variabile viene comunque dedotto in fase di compilazione e non può essere modificato in seguito.

3. Uso illegale di var

Come accennato in precedenza, var non funzionerà senza l'inizializzatore:

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

Né funzionerebbe se inizializzato con null :

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

Non funzionerà per le variabili non locali:

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

L'espressione lambda richiede un tipo di destinazione esplicito e quindi non è possibile utilizzare var :

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

Lo stesso è il caso con l'inizializzatore di array:

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

4. Linee guida per l'utilizzo di var

Ci sono situazioni in cui var può essere usato legalmente, ma potrebbe non essere una buona idea farlo.

Ad esempio, in situazioni in cui il codice potrebbe diventare meno leggibile:

var result = obj.prcoess();

Qui, sebbene sia un uso legale di var , diventa difficile capire il tipo restituito da process () rendendo il codice meno leggibile.

java.net ha un articolo dedicato sulle linee guida di stile per l'inferenza del tipo di variabile locale in Java che parla di come dovremmo usare il giudizio durante l'utilizzo di questa funzione.

Un'altra situazione in cui è meglio evitare var è nei flussi con una pipeline lunga:

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

L'utilizzo di var può anche dare risultati imprevisti.

Ad esempio, se lo usiamo con l'operatore diamante introdotto in Java 7:

var empList = new ArrayList();

Il tipo di empList sarà ArrayList e non List . Se vogliamo che sia ArrayList , dovremo essere espliciti:

var empList = new ArrayList();

L'utilizzo di var con tipi non denotabili potrebbe causare errori imprevisti.

Ad esempio, se usiamo var con l'istanza della classe anonima:

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

Ora, se proviamo ad assegnare un altro Object a obj , otterremmo un errore di compilazione:

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

Questo perché il tipo dedotto di obj non è Object .

5. conclusione

In questo articolo, abbiamo visto la nuova funzione di inferenza del tipo di variabile locale di Java 10 con esempi.

Come al solito, gli snippet di codice possono essere trovati su GitHub.

Avanti » Miglioramenti delle prestazioni di Java 10