使用通用集合

Chu*_*ker 3 java generics collections arraylist

它编译并成功运行!

List a=new ArrayList<String>();
a.add(new Integer(5));
Run Code Online (Sandbox Code Playgroud)

任何人都能解释一下吗?

anu*_*ava 6

原因是您将变量声明a为原始列表,即List没有任何关联类型:

List a = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

就此而言,即使这将编译并运行:

List a = new ArrayList<Date>();
a.add(new Integer(5));
Run Code Online (Sandbox Code Playgroud)

还有一个关于genericstype erasure这里的说明:

泛型由Java编译器实现为称为擦除的前端转换.类型擦除适用于泛型的使用.使用泛型时,它们会转换为编译时检查和运行时类型转换.

由于类型擦除机制,此代码:

List<String> a = new ArrayList<String>();
a.add("foo");
String x = a.get(0);
Run Code Online (Sandbox Code Playgroud)

被编译成:

List a = new ArrayList();
a.add("foo");
String x = (String) a.get(0);
Run Code Online (Sandbox Code Playgroud)

你的代码类似:

List a = new ArrayList<String>();
a.add(new Integer(5));
Run Code Online (Sandbox Code Playgroud)

被编译成这个(由于类型擦除):

List a = new ArrayList();
a.add(new Integer(5));
Run Code Online (Sandbox Code Playgroud)

因此,不会生成编译或运行时错误.

但是,当您尝试从列表中获取项目时,您会注意到区别:

int i = a.get(0); // compilation error due to type mismatch
Run Code Online (Sandbox Code Playgroud)

这是因为您的列表被声明为原始类型.要避免此错误,您需要使用泛型来声明列表,或者像上面那样执行类型转换.即

在列表中使用泛型类型:

List<Integer> a = new ArrayList<Integer>();
a.add(new Integer(5));    
int i = a.get(0);
Run Code Online (Sandbox Code Playgroud)

或者做这个演员:( 不推荐)

List a=new ArrayList<Date>();
a.add(new Integer(5));
int i = (Integer) a.get(0);
Run Code Online (Sandbox Code Playgroud)

PS:请注意,在运行时无法找到特定类型,例如String用于声明列表对象.