java 没有类型的 ArrayList 泛型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25689673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:27:33  来源:igfitidea点击:

ArrayList Generic without Type

javagenericsarraylist

提问by Kai

recently I read a piece of code which seems weird to me. As we know, we need to initialize the generic type in collections when we need to use them. Also, we know Collections can contain Collections as their elements.

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

The code:

代码:

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;
}}

My question is

我的问题是

  • why can we use ArrayList result = new ArrayList();to create an object, since we have not gave the collection the actual type of element.
  • why can we use result.add(content);to add a collection to a collection with collection "result" is just a plain collection. We have not defined it as a ArrayListof ArrayList
  • 为什么我们可以ArrayList result = new ArrayList();用来创建一个对象,因为我们没有给集合元素的实际类型。
  • 为什么我们可以result.add(content);用来将一个集合添加到一个带有集合“结果”的集合中只是一个普通的集合。我们没有把它定义为一个ArrayListArrayList

回答by Harshad Ranganathan

Just adding up to provide summarized answer

只是加起来提供总结的答案

Old way :

旧方式:

(A) ArrayList result = new ArrayList();

will create an Arraylist to hold "Object"

将创建一个 Arraylist 来保存“对象”



New Way :

新的方法 :

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

this represents an Arraylist which will hold "Integer" objects. This was introduced for compile-time type check purposes.

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



why ?

为什么 ?

Consider the first case. Its input type is Object. We know that Object is the super class of all classes. We can pass in an Integer object, String object and so on. When fetching the data the developer has to perform proper type casting. Say if the developer initially thinks the code will accept Integer objects so he adds the following typecast while fetching the data

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

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

This is supposed to work. But if mistakenly he passes a String it will result in run-time error.

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

How it can be avoided ?

如何避免?

By introducing compile time checks

通过引入编译时检查



How it works ?

怎么运行的 ?

when we specify parameterized type only Integer objects can be added to the ArrayList collection. Else it will show error.

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

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

If parameterized generic types are for type checking purposes how correct data can be retrieved from the list ?

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

The compiler implicitly performs type conversion. See the sample code

编译器隐式地执行类型转换。查看示例代码

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

What the compiler actually does when you perform compilation ?

当您执行编译时,编译器实际上做了什么?

//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);


Conclusion

结论

If you see the codes (A) and (B) both are the same. Only difference is that in the second case the compiler implicitly does the same operation.

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

Finally to answer your question ...

终于回答你的问题了...

ArrayList result = new ArrayList();

is allowed for backward compatibility purposes. Although this is not recommended.

出于向后兼容的目的而允许。虽然不推荐这样做。

Official link from Oracle docsexplaining the same concept.

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

回答by Ross Drew

Java generic collections are not stored with a type to ensure backwards compatibility with pre J2SE 5.0. Type information is removed when added to a generic collection. This is called Type Erasure.

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

This means that a generic collection can be assigned to a non generic reference and objects in a generic typed collection can be placed in an non generic, nontyped collection.

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

All Java generics really does is make sure you can't add the wrong type to a generic list and saves you from doing an explicitcast on retrieval; even though it is still done implicitly.

所有 Java 泛型真正做的就是确保您不能将错误的类型添加到泛型列表中,并避免在检索时进行显式转换;即使它仍然是隐式完成的。

Further to this

更进一步

回答by ne1410s

It may be a remnant from before generics came along to java (Java 4 or 5 I think).

它可能是泛型出现在 Java 之前的残余(我认为是 Java 4 或 5)。

回答by Ravi Kiran

Generics were added to Java only in Java 5. Before that, when you use a collection, it always meant collection of objects. The old syntax is left as is for backward compatibility. So ArrayList result = new ArrayList()is actually creating an ArrayList<Object>. Since ArrayList is also an object, you can add contentto the variable result.

泛型仅在 Java 5 中添加到 Java 中。在此之前,当您使用集合时,它总是指对象的集合。为了向后兼容,旧语法保持原样。所以, ArrayList result = new ArrayList()实际上是创建一个ArrayList<Object>。由于 ArrayList 也是一个对象,因此您可以添加content到变量result.

回答by Adi

why can we use ArrayList result = new ArrayList();to create an object, since we have not give the collection the actual type of element.

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

Because java wants to it backward compatible. Generics is more of compiler feature for ensure type safety, collections can store any type of object at runtime.

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

Java compiler will not give you compiler errorfor this but it must have given you compiler warningthat it is unsafe to use generic classes without type.

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