36 votes

Java 10: Diamond Inference de Java 7 fonctionnera-t-il avec l'inférence de type locale?

De JEP 286, nous voyons que nous allons être en mesure d'utiliser les locaux de l'inférence de type (var) dans le JDK 10 (18.3). Le JEP, précise que compile, qui est prévu:

var list = new ArrayList<String>();  // infers ArrayList<String>

Je suis curieux de savoir ce qui se passerait si nous essayons suivantes:

var list = new ArrayList<>();

En effet, ce que j'ai proposée dans le deuxième extrait de la phase de compilation? Si oui (ce dont je doute), l' ArrayList acceptent Object comme son type générique?

Je vais l'essayer moi-même, mais je n'ai pas accès à toutes les machines qui je peux installer des versions préliminaires sur.

Merci!

29voto

orionll Points 1045

Oui, var et l'opérateur diamantaire peuvent être combinés ensemble. Le compilateur déduira le type générique le plus spécifique:

 var list = new ArrayList<>(); // Infers ArrayList<Object>
var list = new ArrayList<>(List.of(1, 2, 3)); // Infers ArrayList<Integer>
 

Et vous pouvez même les combiner avec une classe anonyme:

 var list = new ArrayList<>() {};
 

22voto

Brian Goetz Points 6062

"Travailler avec" vague est question, de sorte que vous êtes susceptible d'obtenir des réponses vagues.

L'inférence de Type n'est pas de lecture de l'esprit; c'est juste la résolution de contraintes. Le moins de contraintes de type disponibles, le plus vous êtes susceptible de rencontrer d'échec ou de résultat surprenant (déduire un type que vous ne vous attendiez pas, comme Object.)

Diamant dit: les types j'ai besoin sont probablement déjà présente sur le côté gauche, pourquoi les répéter sur la droite.

Variable locale de type inférence dit: les types j'ai besoin sont probablement déjà présente sur le côté droit, pourquoi les répéter sur la gauche.

Méthode générique invocation dit: les types j'ai besoin sont probablement déjà présente dans les arguments, pourquoi répéter comme témoins.

Si suffisamment d'informations de type sont disponibles dans le programme sans qu'il soit manifeste constructeur arguments de type ou d'un type de cible sur la gauche, tout ira bien. Par exemple:

List<String> anotherList = ...
var list = new ArrayList<>(anotherList);

Ici, le compilateur est capable de déduire le paramètre de type d' ArrayList en regardant le type de l'argument du constructeur (celui qui prend Collection<? extends E>). Donc il en déduit T=String sur les RHS, et est alors en mesure de déduire ArrayList<String> sur la LHS.

En d'autres termes, le compilateur va faire ce qu'il peut compte tenu de l'information que vous avez donnée. Le moins d'informations que vous lui donner, le plus probable, il va échouer ou de ne pas faire ce que vous voulez.

Cela dit, je pense que vous vous êtes posé la mauvaise question. La question de la façon dont beaucoup vous pouvez laisser de côté ne doit pas être influencé par "quel sera le compilateur me laisser partir, mais de "l'importance des dégâts que je fais à la lisibilité de mon programme." La lecture du code est plus important que d'écrire du code. Laissant de côté tout ce que vous pouvez éventuellement laisser est peu probable afin de maximiser la lisibilité. Vous devez vous efforcer de laisser en assez pour s'assurer qu'aucun lecteur n'est confus lorsqu'il est confronté à votre programme.

12voto

nullpointer Points 1135

Oui, il faudrait compiler. Le var dans le code

var list = new ArrayList<>();

doit être déduit comme étant de type ArrayList<Object> (je crois que l'on peut précisément pas de déterminer le type exact de l'élément en raison de l'effacement), qui serait de même que l'utilisation d'un code tel que:-

ArrayList list = new ArrayList<>(); 
// without the type of the element of list specified

list est finalement déduit que ArrayList<Object>.


À partir de la FAQ sur la liste de diffusion par Brian :-

Qu'advient-il si nous demandons pour l'inférence sur les deux côtés?

Si vous dites:

var x = new ArrayList<>() 

alors que vous demandez pour le compilateur en déduire le type de l'argument d' List, et le type d' x.

Mais vous n'avez pas fourni assez informations de type pour le compilateur pour faire un bon travail.

Dans la plupart des cas, vous obtiendrez une information d'erreur du compilateur vous dire que vous demandez pour votre esprit d'être lu. Dans certains cas, nous allons tomber de retour à déduire Object, comme nous le font actuellement avec:

Object o = new ArrayList<>()  // always inferred ArrayList<Object> here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X