La deuxième déclaration serpente plus ou moins équivalente à la première, mais seulement parce que les médicaments génériques sont effacés lors de l'exécution. Vous obtiendrez un avertissement "conversion non contrôlée", c'est pourquoi je ne l'aime pas.
Une meilleure façon est d'avoir une méthode générique statique comme ceci:
public static <T> List<T> newList() {
return new ArrayList<T>();
}
puis faire
List<String> test = newList();
C'est ce que Google Collections fait.
(Et vous devriez presque toujours déclarerait vos listes comme List
, pas ArrayList
rend facile de changer la mise en œuvre plus tard..)
Edit: dribeas demandé dans les commentaires ce que la différence exacte entre les deux déclarations, et pourquoi j'ai dit qu'elles sont "plus ou moins équivalentes". En raison de type erasure, la seule différence entre eux est l'avertissement. Voici un petit morceau de code les comparer:
import java.util.*;
class GenericDeclarationTest {
public static void main(String[] args) {
List<String> list1 = new ArrayList<String>();
list1.add("");
String s1 = list1.get(0);
List<String> list2 = new ArrayList();
list2.add("");
String s2 = list2.get(0);
}
}
Et voici le bytecode généré (comme imprimé par javap -c GenericDeclarationTest
):
Compiled from "GenericDeclarationTest.java"
class GenericDeclarationTest extends java.lang.Object{
GenericDeclarationTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #4; //String
11: invokeinterface #5, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: iconst_0
19: invokeinterface #6, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
24: checkcast #7; //class java/lang/String
27: astore_2
28: new #2; //class java/util/ArrayList
31: dup
32: invokespecial #3; //Method java/util/ArrayList."<init>":()V
35: astore_3
36: aload_3
37: ldc #4; //String
39: invokeinterface #5, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
44: pop
45: aload_3
46: iconst_0
47: invokeinterface #6, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
52: checkcast #7; //class java/lang/String
55: astore 4
57: return
}
Comme vous pouvez le voir (si vous avez la patience), les deux sont identique. Par ailleurs, cela peut devenir plus facile dans Java 7. Il existe un proposal dans Project Coin pour "Inférence de type améliorée pour la création d'instance générique". Si elle fait la coupe finale, la syntaxe sera:
List<String> test = new ArrayList<>();
// or
Map<String, Object> test2 = new HashMap<>();
Pas trop difficile à saisir, est-il?
était le après dans votre code « statique » intentionnel? Quel est son but ? –
euphoria83
@ euphoria83: Le permet au compilateur de savoir qu'il s'agit d'une méthode générique. Voir page 7 et suivantes de http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf. –
Quelle est la différence entre: Liste x = new ArrayList(); et votre fonction intermédiaire? Et quand vous dites que le premier et le deuxième exemple sont plus ou moins équivalents, quelles sont les différences? –