Java 泛型 - ArrayList 初始化 [英] Java generics - ArrayList initialization

查看:40
本文介绍了Java 泛型 - ArrayList 初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,arraylist init.应该是这样

It is known that arraylist init. should be like this

ArrayList<A> a = new ArrayList<A>();
ArrayList<Integer> a = new ArrayList<Number>(); // compile-time error

那么,为什么java允许这些?

so, why does java allow these ?

1. ArrayList<? extends Object> a1 = new ArrayList<Object>();
2. ArrayList<?> a2 = new ArrayList<Integer>();

那么,如果它们是正确的,为什么不允许这些?

then, if they are correct why doesn't allow these ?

1. a1.add(3);
2. a2.add(3);

编译器消息是:ArrayList 类型中的方法 add(int, capture#1-of ? extends Object) 不适用于参数 (int)

the compiler message is : The method add(int, capture#1-of ? extends Object) in the type ArrayList is not applicable for the arguments (int)

更一般的

  1. a1.add(null e);
  2. a2.add(? e);

我读到了这个,但很高兴收到你的来信.谢谢

I read about this but it is good to hear from you. thanks

另一个有趣的地方是:

 ArrayList<ArrayList<?>> a = new ArrayList<ArrayList<?>>(); // correct
 ArrayList<?> a = new ArrayList<?>(); // wrong. I know it's reason but I have some 
question in my mind that mentioned above 

推荐答案

您不能将 List 分配给 List 类型的引用因为 List 允许 Integer 以外的数字类型.如果您被允许这样做,则将允许以下内容:

You can't assign a List<Number> to a reference of type List<Integer> because List<Number> allows types of numbers other than Integer. If you were allowed to do that, the following would be allowed:

List<Number> numbers = new ArrayList<Number>();
numbers.add(1.1); // add a double
List<Integer> ints = numbers;
Integer fail = ints.get(0); // ClassCastException!

类型 List 保证它包含的任何内容都是 Integer.这就是为什么您可以在不进行强制转换的情况下从中获取 Integer 的原因.如您所见,如果编译器允许将其他类型的 List(例如 Number)分配给 List,则保证将被打破.

The type List<Integer> is making a guarantee that anything it contains will be an Integer. That's why you're allowed to get an Integer out of it without casting. As you can see, if the compiler allowed a List of another type such as Number to be assigned to a List<Integer> that guarantee would be broken.

List 分配给类型的引用,例如 ListList 是合法的,因为 ? 的意思是给定类型的一些未知子类型"(其中类型是 Object 在只有 ?Number? extends Number 的情况下).

Assigning a List<Integer> to a reference of a type such as List<?> or List<? extends Number> is legal because the ? means "some unknown subtype of the given type" (where the type is Object in the case of just ? and Number in the case of ? extends Number).

由于 ? 表示您不知道List 将接受什么特定类型的对象,因此添加任何内容都是不合法的但是 null 给它.但是,您可以从它检索任何对象,这是使用 的目的吗?扩展 X 有界通配符类型.请注意,对于 ?super X 有界通配符类型...一个 List 是一些未知类型的列表,它至少是 Integer 的超类型".虽然你不知道它是什么类型的 List(可能是 List, List, List) 您确实知道,无论它是什么,都可以向其中添加 Integer.

Since ? indicates that you do not know what specific type of object the List will accept, it isn't legal to add anything but null to it. You are, however, allowed to retrieve any object from it, which is the purpose of using a ? extends X bounded wildcard type. Note that the opposite is true for a ? super X bounded wildcard type... a List<? super Integer> is "a list of some unknown type that is at least a supertype of Integer". While you don't know exactly what type of List it is (could be List<Integer>, List<Number>, List<Object>) you do know for sure that whatever it is, an Integer can be added to it.

最后,new ArrayList<?>() 是不合法的,因为当你创建一个像 ArrayList 这样的参数化类的实例时,你必须给出特定类型参数.你真的可以在你的例子中使用任何东西(ObjectFoo,没关系)因为你永远无法添加任何东西,除了 null 给它,因为您将它直接分配给 ArrayList 引用.

Finally, new ArrayList<?>() isn't legal because when you're creating an instance of a paramterized class like ArrayList, you have to give a specific type parameter. You could really use whatever in your example (Object, Foo, it doesn't matter) since you'll never be able to add anything but null to it since you're assigning it directly to an ArrayList<?> reference.

这篇关于Java 泛型 - ArrayList 初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆