ArrayList Generic没有Type

时间:2014-09-05 15:50:57

标签: java generics arraylist

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

代码:

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

我的问题是

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

5 个答案:

答案 0 :(得分:10)

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

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

所有Java泛型确实做的是确保您不能将错误的类型添加到通用列表中,并避免在检索时执行explicit强制转换;即使它仍然完成implicitly

继续

答案 1 :(得分:9)

只需加起来提供总结答案

旧方式:

(A) ArrayList result = new ArrayList();

将创建一个Arraylist来持有&#34; Object&#34;


新方式:

ArrayList<Integer> content = new ArrayList<Integer>();

这代表一个Arraylist,它将持有&#34; Integer&#34;对象。这是为编译时类型检查而引入的。


  

为什么?

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

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

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

  

如何避免?

引入编译时检查


  

它如何运作?

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

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

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

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

List<Integer> list=new ArrayList<Integer>();
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 docs的官方链接,解释了相同的概念。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

  

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

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

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