当前位置: 首页 > 面试题库 >

Java泛型-ArrayList初始化

洪建茗
2023-03-14
问题内容

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

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

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

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

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

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

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

更一般

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

我读到了这件事,但很高兴收到您的来信。谢谢

另一个有趣的地方是:

 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<Number>为类型的引用分配,List<Integer>因为它List<Number>允许使用除以外的数字类型Integer。如果允许您这样做,则将允许以下操作:

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。这就是为什么您Integer无需铸造就可以退出的原因。如您所见,如果编译器允许将List另一种类型的Number分配给a
List<Integer>,则保证将被破坏。

分配List<Integer>到例如类型的基准List<?>List<? extends Number>是合法的,因为?装置(其中的类型是“给定的类型的一些未知的子类型”
Object中的只是的情况下?Number在的情况下? extends Number)。

由于?表明您 不知道List将接受哪种特定类型的对象,因此只能null向其中添加任何内容。但是,允许您从其中 检索
任何对象,这是使用有? extends X界通配符类型的目的。请注意,对于有? super X界通配符类型而言,情况恰恰相反……a List<? super Integer>是“某种未知类型的列表,至少是其超类型Integer”。虽然你不知道到底是什么类型List是(可能是List<Integer>List<Number>List<Object>)你肯定知道不管它是什么,一个Integer可以被添加到它。

最后,这new ArrayList<?>()是不合法的,因为在创建参数化的类(如)的实例时ArrayList,您必须提供 特定的
类型参数。您可以在示例中使用任何内容(ObjectFoo都不要紧),因为您将无法直接添加任何内容null,因为您直接将其分配给了ArrayList<?>引用。



 类似资料:
  • 问题内容: 因此,我正在开发这个通用的HashTable类,并且希望将其通用地用于任何数量的传入类型,并且我还想将内部存储数组初始化为LinkedList的数组(出于冲突目的),其中为确保类型安全,每个LinkedList都被预先指定为HashTable类中的泛型类型。我该怎么做?以下代码最能阐明我的意图,但当然不会编译。 问题答案: Java中的泛型不允许创建具有泛型类型的数组。您可以将数组转换

  • 为什么我可以初始化ArrayList,如下所示: 但在使用时出错:

  • 问题内容: 这个问题不是关于为什么我们将列表初始化为实现的接口,例如 问题是以下两个之间有何区别?为什么它们(显然)以相同的方式工作? 问题答案: 这两段代码是等效的,并使用 类型 创建s (在您的示例中): 但是,第二个示例使用Java 7中引入的 菱形运算符 ()。它添加了类型推断,并减少了赋值的冗长性。 请参阅文档中的以下引用: 您可以用一组空的类型参数()来替换调用通用类的构造函数所需的类

  • 问题内容: 你可以通过执行以下操作来设置ArrayList的初始大小: 但是,你做不到 因为它会导致超出范围的异常。 如果无法访问分配的空间,设置初始大小有什么用? add函数的定义是,所以我不添加索引10。 问题答案: 你将数组列表的大小与其容量混淆了: 的大小是在列表中的元素的数目; 的容量是多少元素列表可以潜在地容纳而不重新分配其内部结构。 呼叫时,你是在设置列表的初始容量,而不是列表的大小

  • 问题内容: 我想创建用于测试目的的选项列表。首先,我这样做: 然后,我将代码重构如下: 有一个更好的方法吗? 问题答案: 实际上,初始化的“最佳”方法可能ArrayList是你编写的方法,因为它无需以List任何方式创建新方法: 问题是引用该实例需要大量输入。 还有其他选择,例如使用实例初始化程序(也称为“双括号初始化”)创建匿名内部类: 但是,我不太喜欢这种方法,因为最终得到的是ArrayLis

  • 我有一个非常基本的问题。我需要如何为ArrayList键入parrameters才能在BlueJ中使用代码?我有一个方法如下。