Inférence de type Java 10 LocalVariable

Inférence de type de variable locale Java 10

1. Vue d'ensemble

L'une des améliorations les plus visibles du JDK 10 est l'inférence de type de variables locales avec des initialiseurs.

Ce tutoriel fournit les détails de cette fonctionnalité avec des exemples.

2. introduction

Jusqu'en Java 9, nous devions mentionner explicitement le type de la variable locale et nous assurer qu'elle était compatible avec l'initialiseur utilisé pour l'initialiser:

String message = "Good bye, Java 9";

En Java 10, voici comment nous pourrions déclarer une variable locale:

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

Nous ne fournissons pas le type de donnéesmessage. Au lieu de cela, nous marquonsthe message  comme unvar, et le compilateur déduit le type demessage  à partir du type de l'initialiseur présent sur le côté droit.

Dans l'exemple ci-dessus, le type demessage devrait êtreString.

Note that this feature is available only for local variables with the initializer. Il ne peut pas être utilisé pour les variables membres, les paramètres de méthode, les types de retour, etc. - l'initialiseur est requis car sans lequel le compilateur ne pourra pas déduire le type.

Cette amélioration aide à réduire le code standard; par exemple:

Map map = new HashMap<>();

Cela peut maintenant être réécrit comme:

var idToNameMap = new HashMap();

Cela permet également de se concentrer sur le nom de la variable plutôt que sur le type de variable.

Une autre chose à noter est quevar is not a keyword - cela garantit la compatibilité descendante pour les programmes utilisantvar say, comme fonction ou nom de variable. var est un nom de type réservé, tout commeint.

Enfin, notez qu'il existeno runtime overhead in using var nor does it make Java a dynamically typed language.  Le type de variable est toujours déduit au moment de la compilation et ne peut pas être modifié ultérieurement.

3. Utilisation illégale devar

Comme mentionné précédemment,var w ne fonctionne pas sans l'initialiseur:

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

Cela ne fonctionnerait pas non plus s'il était initialisé avecnull:

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

Cela ne fonctionnera pas pour les variables non locales:

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

L'expression Lambda nécessite un type de cible explicite, et par conséquentvar cannot être utilisé:

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

Même est le cas avec l'initialiseur de tableau:

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

4. Directives d'utilisation devar

Il y a des situations oùvar can est utilisé légalement, mais ce n'est peut-être pas une bonne idée de le faire.

Par exemple, dans des situations où le code pourrait devenir moins lisible:

var result = obj.prcoess();

Ici, bien qu'une utilisation légale devar, il devient difficile de comprendre le type retourné par leprocess()rendant le code moins lisible.

java.netpartage un article dédié surStyle Guidelines for Local Variable Type Inference in Java qui explique comment utiliser le jugement lors de l'utilisation de cette fonctionnalité.

Une autre situation où il vaut mieux évitervar is dans les flux avec un long pipeline:

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

L'utilisation devar may donne également un résultat inattendu.

Par exemple, si nous l’utilisons avec l’opérateur diamant introduit dans Java 7:

var empList = new ArrayList<>();

Le type deempListwill estArrayList<Object>and et nonList<Object>. Si nous voulons que ce soitArrayList<Employee>, il faudra être explicite:

var empList = new ArrayList();

L'utilisation devar w avec des types non dénotables peut provoquer une erreur inattendue.

Par exemple, si nous utilisonsvar w avec l'instance de classe anonyme:

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

Maintenant, si nous essayons d'assigner un autreObjecttoobj, nous obtiendrons une erreur de compilation:

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

En effet, le type inféré deobj  n’est pasObject.

5. Conclusion

Dans cet article, nous avons vu la nouvelle fonctionnalité d'inférence de type de variable locale Java 10 avec des exemples.

Comme d'habitude, des extraits de code peuvent être trouvésover on GitHub.