Je ne sais pas pourquoi ça compile. En revanche, je peux vous expliquer comment tirer pleinement parti des vérifications à la compilation.
Donc, newList()
est une méthode générique, elle a un paramètre de type. Si vous spécifiez ce paramètre, le compilateur le vérifiera pour vous :
Ne parvient pas à compiler :
String s = Main.<String>newList(); // this doesn't compile anymore
System.out.println(s);
Passe l'étape de la compilation :
List<Integer> l = Main.<ArrayList<Integer>>newList(); // this compiles and works well
System.out.println(l);
Spécifier le paramètretype
Les paramètres de type ne permettent qu'une vérification au moment de la compilation. C'est à dessein, java utilise effacement de type pour les types génériques. Pour que le compilateur travaille pour vous, vous devez spécifier ces types dans le code.
Paramètre de type lors de la création de l'instance
Le cas le plus courant est de spécifier les modèles pour une instance d'objet. Par exemple, pour des listes :
List<String> list = new ArrayList<>();
Ici, nous pouvons voir que List<String>
spécifie le type des éléments de la liste. D'autre part, la nouvelle ArrayList<>()
ne le fait pas. Il utilise le opérateur de diamant à la place. C'est-à-dire le compilateur java déduit le type basé sur la déclaration.
Paramètre de type implicite à l'invocation de la méthode
Lorsque vous invoquez une méthode statique, vous devez alors spécifier le type d'une autre manière. Parfois, vous pouvez le spécifier en tant que paramètre :
public static <T extends Number> T max(T n1, T n2) {
if (n1.doubleValue() < n2.doubleValue()) {
return n2;
}
return n1;
}
Vous pouvez l'utiliser comme ceci :
int max = max(3, 4); // implicit param type: Integer
Ou comme ça :
double max2 = max(3.0, 4.0); // implicit param type: Double
Paramètres de type explicites lors de l'invocation de la méthode :
Par exemple, voici comment vous pouvez créer une liste vide sécurisée par un type :
List<Integer> noIntegers = Collections.<Integer>emptyList();
Le paramètre de type <Integer>
est transmis à la méthode emptyList()
. La seule contrainte est que vous devez également spécifier la classe. C'est-à-dire que vous ne pouvez pas faire cela :
import static java.util.Collections.emptyList;
...
List<Integer> noIntegers = <Integer>emptyList(); // this won't compile
Jeton de type d'exécution
Si aucune de ces astuces ne peut vous aider, vous pouvez alors spécifier un jeton de type d'exécution . C'est-à-dire que vous fournissez une classe en tant que paramètre. Un exemple courant est le EnumMap :
private static enum Letters {A, B, C}; // dummy enum
...
public static void main(String[] args) {
Map<Letters, Integer> map = new EnumMap<>(Letters.class);
}