当前位置: 首页 > 知识库问答 >
问题:

为什么这行不编译listl=new arraylist()?[副本]

李兴安
2023-03-14

我想能列一张这样的单子-

List<Object> l = new ArrayList<String>();

arraylist的标准库实现不允许这样做。它会给出编译时错误。因此,我正在编写自己的ArrayList实现。

到目前为止我已经试过了-

public class ArrayList<Y extends X> implements List<X> {...}
public class ArrayList<X super Y> implements List<X> {...}

那么,如何编写一个能够像上面提到的那样使用它的ArrayList呢?

List<Object> l = new ArrayList<String>();

人们已经指出这篇文章是list 的一个子类list ?为什么Java的泛型不是隐式多态的?

但我还是不明白。给出的理由是我们想避免这样的情况-

List<Object> l = new ArrayList<String>();
l.add(new Dog()); 

虽然这是有意义的,但我可以用Java数组做类似的事情,它在运行时编译但抛出异常。

Object o[] = new String[10];
o[0] = new Dog();

编辑--如上文所示,已经提出了类似的问题。这个问题也有助于为什么ArrayStoreException是RuntimeException?

共有1个答案

于捷
2023-03-14

正如您的链接所说,定义您的列表,如下所示:

List<? extends Object> l = new ArrayList<String>();

编辑

是的,原因是

List<? extends Object> l = new ArrayList<String>(); l.add("asda");

不起作用的是避免运行时异常,因为列表的类型可能是扩展object的任何内容,所以编译器将其作为扩展内容(可能是任何内容/未知内容)处理。但是,如果您保留对原始列表的引用,您仍然可以编辑该列表。

List<String> strList = new ArrayList<>();
List<? extends Object> objList = strList;
strList.add("asdf");
// Will return Strings that only have the Object interface
Object o = objList.get(0);

<代码>列表<的目的是什么?extends Object>只是为您的代码提供一个类型保证(在本例中是某个类型extendingObject),由于泛型,编译器能够在编译时确保该条件,但它还需要确保您不会违反原始列表。以以下代码为例:

List<Integer> intList = new ArrayList<>();
List<? extends Object> objList = intList;
// compile error to protect the original list
objList.add("asdf");

因此,由于对象列表的类型为,因此不能向其添加字符串。尽管stringobject的子类,但它可能与不是(在本例中也不是)同一类型。

另外,不要忘记,由于类型擦除,泛型类型在运行时会消失。泛型是编译时间的保证。

还有,现在我看到你真正的问题了。

我需要的理由,为什么相同的事情允许数组,为什么不编译时错误在这种情况下?基本上,我想问的是,为什么我们有这个双重策略,一个用于数组,另一个用于泛型数组列表?

请参阅此问题及其相关答案

 类似资料:
  • 问题内容: 如果你给 它没有编译,但是带有花括号的相同代码是: 有什么解释? 问题答案: 基本上,变量声明只能在块中声明。 查看 Java语言规范中“语句”的语法 -它包括Block,但不包括LocalVariableDeclarationStatement- 后者是block语法的一部分。 这实际上是实用主义的问题:如果没有括号,则只能使用一个语句。如果没有后续语句,则声明变量是没有意义的,因为

  • 奇怪的是,标记为“OK”的行编译得很好,但标记为“Error”的行失败了。它们看起来基本上是一样的。

  • 此代码可编译但不运行;当我试图运行这个程序时,它会给出一个。我做错了什么?

  • 我知道不同的平台有不同的UI需求,但为什么我必须下载源代码并自己编译它呢?为什么我不能为我的平台下载一个可运行的版本?

  • 我在Mac OS X上使用Java8编译了一个简单的Java文件到assembly。这是test.Java:

  • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用