在实例化泛型类时传递类型变量

时间:2010-12-11 05:10:58

标签: java generics

有人可以解释ArrayList类的这两个实例之间的差异吗?

List<Integer> intList = new  ArrayList();
List<Integer> intList = new  ArrayList<Integer>();

我知道编译器在将其编译为字节码时擦除了类型变量,即Integer,上面的例子都完全相同。我想知道在右侧传递类型变量(Integer)是否有任何好处,因为它已经在左侧声明了?就我在网上找到的而言,他们都使用后者,但我看不出有什么理由要在双方都宣布两次。

3 个答案:

答案 0 :(得分:3)

他们是两件不同的事。左侧是变量的类型。右侧是您正在创建的对象的类型。编译器将首先使用您在右侧给出的类型创建对象,然后将引用分配给左侧的变量。

在您的情况下,没有区别,因为ArrayList在所有情况下都具有相同的构造函数。但是:

  • 在其他类中,构造函数可能会根据您提供的特定类型而有所不同。
  • 如果匹配类型,您将在编译器上更容易。在第一个版本中,编译器必须将类型为ArrayList的对象分配给期望List<Integer>类型的变量。在某些情况下,您可能会收到警告,因为类型不明显匹配。

答案 1 :(得分:2)

没有type参数的版本会产生警告,因为它可能不是类型安全的。在你的情况下,这不是一个问题,因为列表是空的,但通常它是。例如

List<String> stringList = new ArrayList<String>();
stringList.add("foo");
List<Integer> intList = new ArrayList(stringList); // Warning about unchecked conversion
int i = intList.get(0); // Oops, throws a ClassCastException

因此,为确保类型安全,最好通过在任何地方添加类型参数来消除警告。

答案 2 :(得分:0)

你可能想要区别:

List intList = new  ArrayList();
List<Integer> intList = new  ArrayList<Integer>();

它们在运行时都是相同的。但编译时间存在很大差异。