List<String> v = new ArrayList<String>();
我理解泛型可以帮助您声明ArrayList()具有String类型的对象。我的问题是 以下是如何与上述不同的?
List<String> v = new ArrayList();
或以下与其他人不同的
List v = new ArrayList<String>();
答案 0 :(得分:4)
List<String> v = new ArrayList();
这个并不是真正的功能差异。右侧的类型参数实际上没有做任何事情。它被用作样式的问题并且避免使用Raw类型,这被认为是编程错误。实际上,在Java 7中它已被增强,所以你可以这样做:List<String> v = new ArrayList<>();
而不必在右侧重复自己。
List v = new ArrayList<String>();
没有类型参数的列表称为原始类型。在使用泛型的新代码中声明原始类型通常被认为是编程错误。基本上,当您以这种方式声明时,根本没有进行类型检查,您可以在该列表中放置任何内容。
Java泛型是一个编译时间检查。因此,编译时引用的类型很重要。如果您的引用是Raw List
类型,那么您在右侧声明的内容并不重要,这就是编译器将检查的内容。
List<String>
实际上不是“包含字符串的列表”。这是一个“列表,我已经要求编译器返回错误和/或警告我,如果我在那里放一些不是字符串的东西。如果你忽略编译器警告,很有可能在那里得到的东西不是'一个字符串。
答案 1 :(得分: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
}
答案 2 :(得分:1)
List v = new ArrayList();
这是在java 5声明列表之前的方式。
List<String> v = new ArrayList<String>();
它使用了java中引入的泛型。它增加了编译时类型的安全性。
List<String> v = new ArrayList<>();
只是java 7中引入的一个优化。它只是简化了代码 通过保持类型安全
答案 3 :(得分:0)
在第一个和第三个案例(new ArrayList<String>()
)中,您实例化了一个可以容纳ArrayList
个实例的String
在第二种情况下(new ArrayList()
),您实例化ArrayList
可以容纳Object
个实例(即任何类型的实例 - 甚至混合和匹配)
在第一个和第二个案例(ArrayList<String> v
)中,您声明了一个可以容纳ArrayList
个实例的String
个实例
在第三种情况下(ArrayList v
),您声明了一个ArrayList
的实例,该实例可以包含Object
的实例。
第二种情况的问题是,如果你要获得一个“原始”ArrayList
(就像那个实例化的那样),那么它理论上可以容纳任何东西;不只是String
个实例,这是声明用户所期望的。
同样,在第三种情况下,您创建了一个ArrayList
,它应该保留String
,但声明的用户不知道并且可能尝试将其他对象实例放入其中
注意:当然,在JVM中,泛型类型信息会丢失,因此执行方面没有区别,但是对于编程类型安全性,编译器会标记错误的使用。这样,就不需要动态检查/确保放入/放出列表的对象的类型 - 你可以假设它们是正确的类型,因为编译器确保了这个
答案 4 :(得分:0)
这些全部编译,都是有效的。第二种情况可能只会发出警告 - 由于List<String>
,您将无法添加任何非字符串的内容。在第三种情况下,你有相反的问题。您可以添加不是字符串的内容,但结果可能会遇到运行时异常。