3
 List<String> v = new ArrayList<String>();

我了解泛型可以帮助您声明 ArrayList() 具有字符串类型的对象。我的问题是以下与上述有何不同?

 List<String> v = new ArrayList();

或以下与其他不同的

List v = new ArrayList<String>();
4

5 回答 5

4
List<String> v = new ArrayList();

这个在功能上并没有什么不同。右侧的类型参数实际上并没有做任何事情。它被用作风格问题并避免使用 Raw 类型,这被认为是编程错误。事实上,在 Java 7 中它已得到增强,因此您可以这样做:List<String> v = new ArrayList<>();而不必在右侧重复自己。

List v = new ArrayList<String>();

没有类型参数的列表称为原始类型。在使用泛型的新代码中声明原始类型通常被认为是编程错误。基本上,当您以这种方式声明它时,根本不会进行类型检查,您可以将任何内容放入该列表中。

Java 泛型是一种编译时检查。因此,重要的是编译时引用的类型。如果您的引用是 Raw 类型List,那么您在右侧声明的内容无关紧要,这就是编译器将检查的内容。

List<String> 并不是真正的“具有字符串的列表”。这是一个“我已经要求编译器返回错误和/或警告我的列表,如果我在其中放入了不是字符串的内容。如果您忽略编译器警告,那么完全有可能在其中获取那些不是字符串的东西” t 字符串。

于 2012-04-10T17:46:21.250 回答
1
public static void main(String[] args) throws Exception {
    List<String> list1 = new ArrayList<String>();
    List<String> list2 = new ArrayList(); //This is equivalent to list1 but with compilation warning
    List list3 = new ArrayList<Integer>(); //This is equivalent to list3 = new ArrayList<Object>()
    //list1.add(new Object()); //does not compile
    //list2.add(new Object()); //does not compile
    list3.add(new Object()); //this is fine
    list1 = list3; //ok, but
    System.out.println(list3.get(0)); // this is fine
    System.out.println(list1.get(0)); //Runtime error: ClassCastException
    //List<Object> list5 = list1; //does not compile        
    List<Object> list5 = list3; //ok
}
于 2012-04-10T17:41:23.257 回答
1
List v = new ArrayList();

它在 java 5 声明列表的方式之前。

List<String> v = new ArrayList<String>();

它使用 java 5 中引入的泛型。它增加了编译时类型安全性。

List<String> v = new ArrayList<>(); 

只是 java 7 中引入的优化。它只是通过维护类型安全来简化代码

于 2012-04-10T17:44:03.623 回答
0

在第一种和第三种情况(new ArrayList<String>())中,您实例化一个ArrayList可以容纳String实例的

在第二种情况下(new ArrayList()),您实例化一个ArrayList可以容纳Object实例的实例(即任何类型的实例——甚至混合匹配)

在第一种和第二种情况(ArrayList<String> v)中,您声明一个ArrayList可以容纳实例的String实例

在第三种情况 ( ArrayList v) 中,您声明了一个ArrayList可以容纳Object.

第二种情况的问题在于,如果您要获得“原始” ArrayList(例如实例化的),那么理论上它可以容纳任何东西;不仅仅是String实例,这是声明的用户所期望的。

同样,在第三种情况下,您创建了一个ArrayList应该包含Strings 的对象,但声明的用户不知道这一点,并且可能会尝试将其他对象实例放入其中

注意:当然在后台,在JVM中,泛型类型信息丢失了,所以在执行方面没有区别,但是为了编程类型安全,编译器会标记错误的使用。这样,就不需要动态检查/确保放入/离开列表的对象的类型——你可以假设它们是正确的类型,因为编译器确保了这一点

于 2012-04-10T17:37:58.840 回答
0

这些都可以编译,并且都是有效的。第二种情况可能只会引发警告 - 由于List<String>. 在第三种情况下,您会遇到相反的问题。您可以添加不是字符串的东西,但结果可能会遇到运行时异常。

于 2012-04-10T17:38:18.143 回答