在Java中初始化Generic类的实例时,在语句的两端指定Type是否有任何好处?
换句话说,这两个有效陈述之间的区别是什么:
ArrayListtest = new ArrayList ();
和:
ArrayListtest = new ArrayList();
(似乎第二个陈述不等同于:
ArrayListtest = new ArrayList
作为第三个语句无效并导致incompatible types
编译错误.)
第二个语句或多或少与第一个语句相同,但仅仅是因为泛型在运行时被删除.您将收到"未经检查的转换"警告,这就是我不喜欢它的原因.
更好的方法是使用这样的静态泛型方法:
public staticList newList() { return new ArrayList (); }
然后呢
Listtest = newList();
这就是Google Collections的功能.
(而且你应该几乎总是将你的列表声明为List
,而不是像ArrayList
.稍后切换实现会很容易.)
编辑: dribeas在评论中询问两个声明之间的确切差异,以及为什么我说它们"或多或少相当".由于类型擦除,它们之间的唯一区别是警告.这是一小段代码比较它们:
import java.util.*; class GenericDeclarationTest { public static void main(String[] args) { Listlist1 = new ArrayList (); list1.add(""); String s1 = list1.get(0); List list2 = new ArrayList(); list2.add(""); String s2 = list2.get(0); } }
这是生成的字节码(由打印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."":()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." ":()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." ":()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 }
正如你所看到的(如果你有耐心),两者是相同的.
顺便提一下,这在Java 7中可能变得更容易.在Project Coin中有一个提议 "改进了通用实例创建的类型推断".如果它进行最终剪切,则语法为:
Listtest = new ArrayList<>(); // or Map test2 = new HashMap<>();
打字不太难,是吗?