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