【问题标题】:Why does AbstractCollection.toArray() hide the generic value T?为什么 AbstractCollection.toArray() 隐藏通用值 T?
【发布时间】:2016-02-16 17:40:20
【问题描述】:

作为一个类分配,我必须实现 AbstractCollection 的自定义实现,并使用泛型。我发现AbstractCollection.toArray()隐藏了它默认的T类型如下:

public <T> T[] toArray(T[] a) { ... }

我最初认为以下方法会起作用,但我的 IDE 告诉我它不会覆盖超级:

@Override
public T[] toArray(T[] a) { ... }

所以,然后我将&lt;T&gt; 添加到方法签名中,现在(尽管它会编译)被告知以下内容:

Array of type 'T[]' expected

//Reports two types of suspicious calls to Collection.toArray().
//The first type is any calls where the type of the specified array argument
// is not of the same type as the array type to which the result is casted.
//Example:
void m(List list) {
  Number[] ns = (Number[])
      list.toArray(new String[list.size()]);
}
//The second type is any calls where the type of the specified array argument doesn't match
// the type parameter of the collection declaration.
//Example:
void m(List<Number> list) {
  Number[] ns =
      list.toArray(new String[list.size()]);
}

所以,我的第一个问题是,是否有充分的理由一开始就这样做?其次,这会以任何方式影响我的实施吗?

【问题讨论】:

  • 是否有任何负面的南希愿意向我解释他们为什么不赞成这个问题?我看不出有什么问题。
  • 当你给toArray()方法一个String[]时,返回值为String[],这与Number[]不兼容。如果您想要Number[],请将其作为参数。
  • @LouisWasserman 不完全是,但它可能是相关的。谢谢
  • @agent154 这几乎是您第一个问题的答案——toArray 是这样写的,因为该集合不知道 如何 创建一个适当的数组类型。

标签: java generics


【解决方案1】:

Collection 接口将方法声明为:

<T> T[] toArray(T[] a)

所以你必须在实现类中做同样的事情,否则它不是给定方法的覆盖,而是重载。

这样做是为了向后兼容,因为该方法在泛型添加到语言之前就已经存在。官方 1.4 文档不再在线提供,但您可以在这里(暂时)找到它:https://www.cs.duke.edu/csed/java/jdk1.4.2/docs/api/java/util/Collection.html#toArray%28java.lang.Object[]%29

请记住,List&lt;Number&gt;List&lt;Integer&gt; 在运行时实际上只是一个 List,因为类型擦除。区别是在编译时完成的。另一方面,Number[]Integer[] 在运行时实际上是不同的,如果值的类型错误,则会抛出异常。

这意味着您可以根据自己的选择从List&lt;Integer&gt; 创建Number[]。如果您确定所有列表元素实际上都是Integer 对象,您甚至可以从List&lt;Number&gt; 创建Integer[]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-28
    • 2023-03-23
    • 2015-11-12
    • 1970-01-01
    • 2016-04-29
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多