ArrayList Generic没有Type

最近我读了一段对我来说很奇怪的代码。 我们知道,我们需要在需要使用它们时初始化集合中的generics类型。 此外,我们知道集合可以包含集合作为其元素。

代码:

public class Solution { public static void main(String args[]) { ArrayList res = returnlist(); System.out.print(res.get(0)); } public static ArrayList<ArrayList> returnlist() { ArrayList result = new ArrayList(); ArrayList content = new ArrayList(); content.add(1); result.add(content); return result; }} 

我的问题是

  • 为什么我们可以使用ArrayList result = new ArrayList(); 创建一个对象,因为我们没有给集合提供实际的元素类型。
  • 为什么我们可以使用result.add(content); 将集合添加到集合“result”的集合只是一个简单的集合。 我们还没有将它定义为ArrayListArrayList

Javagenerics集合不与类型一起存储,以确保与J2SE 5.0之前的向后兼容性。 添加到通用集合时,将删除类型信息。 这称为类型擦除 。

这意味着可以将generics集合分配给非generics引用,并且可以将generics类型集合中的对象放置在非generics非类型集合中。

所有Javagenerics实际上都确保您不能将错误的类型添加到通用列表中,并使您免于对检索进行显式强制转换; 即使它仍然是隐含的 。

除此之外

  • 这个答案的Java部分更深入到我刚才所说的内容
  • 本文还基本涵盖了您以更完整的方式提出的问题
  • Type Erasure 需要注意的其他事项

只需加起来提供总结答案

旧方式:

 (A) ArrayList result = new ArrayList(); 

将创建一个Arraylist来持有“对象”


新方法 :

 ArrayList content = new ArrayList(); 

这代表一个Arraylist,它将保存“Integer”对象。 这是为编译时类型检查目的而引入的。


为什么?

考虑第一种情况。 它的输入类型是Object。 我们知道Object是所有类的超类。 我们可以传入Integer对象,String对象等。 在获取数据时,开发人员必须执行正确的类型转换。 假设开发人员最初认为代码将接受Integer对象,那么他在获取数据时添加以下类型转换

 Integer integer=(Integer) content.get(0); 

这应该有效。 但是,如果他错误地传递了一个字符串,则会导致运行时错误。

如何避免?

通过引入编译时检查


这个怎么运作 ?

当我们指定参数化类型时,只能将Integer对象添加到ArrayList集合中。 否则它会显示错误。

 content.add(3); // will work content.add("HARSHAD"); // error shown 

如果参数化generics类型用于类型检查,如何从列表中检索正确的数据?

编译器隐式执行类型转换。 请参阅示例代码

 List list=new ArrayList(); list.add(1); list.add(2); Integer integer=list.get(0); System.out.println(integer); 

执行编译时编译器实际执行的操作是什么?

 //perform type erasure (B) List list=new ArrayList(); list.add(1); list.add(2); // the arraylist inturn accepts Object when you run the code //add casting Integer integer=(Integer)list.get(0); 

结论

如果你看到代码(A)和(B)都是相同的。 唯一不同的是,在第二种情况下,编译器隐式地执行相同的操作。

最后回答你的问题……

 ArrayList result = new ArrayList(); 

允许出于向后兼容的目的。 虽然不建议这样做。

来自Oracle文档的官方链接解释了相同的概念。

它可能是仿制药出现在Java之前的遗留物(我认为是Java 4或5)。

generics仅在Java 5中添加到Java中。在此之前,当您使用集合时,它始终意味着对象的集合。 旧语法保留为向后兼容性。 所以ArrayList result = new ArrayList()实际上是在创建一个ArrayList 。 由于ArrayList也是一个对象,因此您可以向变量result添加content

为什么我们可以使用ArrayList result = new ArrayList(); 创建一个对象,因为我们没有给集合提供实际的元素类型。

因为java希望它向后兼容。 generics更多是用于确保类型安全的编译器function,集合可以在运行时存储任何类型的对象。

Java编译器不会为此提供编译器错误 ,但它必须给你编译器警告 ,使用没有类型的generics类是不安全的。