List <t>覆盖toArray以T1 [] toArray结尾

时间:2018-07-06 08:50:03

标签: java android

我试图通过在类中实现List接口来稍微调整List。

除了这一方法之外,我可以毫无问题地重写并实现所有方法:

T1

Android Studio会在覆盖时向我显示此代码,并创建新的类型@NonNull @Override public <T1> T1[] toArray(@NonNull T1[] a) { return inner.toArray(a); } 。 为什么会这样?它有什么作用?

a

将鼠标悬停在java.lang.Object参数上时,会看到以下棉绒警告:

  

预期类型为T[]的数组

当我尝试将其手动更改回T1[]而不是T时,出现此错误:

  'QueryList'中的

toArray(T [])'与'java.util.List'中的'toArray(T [])'冲突;两种方法具有相同的擦除效果,但都不能覆盖另一种方法

这是Android Studio / intelliJ中的错误,它无法正确创建该覆盖,还是我错过了什么?

编辑: 这是该类的声明,包括public class QueryList<T> implements List<T> { //<editor-fold desc="inner list & constructors"> protected final List<T> inner; public QueryList() { inner = new ArrayList<>(); } public QueryList(int initialCapacity) { inner = new ArrayList<>(initialCapacity); } public QueryList(@NonNull Collection<? extends T> c) { inner = new ArrayList<>(c); } //</editor-fold> 及其使用位置。

{{1}}

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

  

不涉及其他T

您的QueryList类声明了一个类型参数,该类型参数也称为T,因此intellij可能会将替代中的参数重命名为T1,以明确表明它是与众不同的。

请注意,List中的toArray也声明了它自己的类型参数,正确覆盖也需要它:

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

我猜您的修复程序也删除了类型参数声明,如下所示:

T[] toArray(T[] a);

但这将不再使其成为替代,因为类型参数必须匹配。根据{{​​3}}:

  

在类C中声明或由类C继承的实例方法mC,从C重写在类A中声明的另一方法mA,前提是以下所有条件均成立:

     

...

     
      
  • mC的签名是mA签名的子签名jls 8.4.8.1
  •   

8.4.2中:

  

两个方法或构造函数M和N,如果它们具有相同的名称,相同的类型参数(如果有的话) (§8.4.2),并且在改正形式后,则具有相同的签名。 N的参数类型与M的类型参数相同,形式参数类型相同。

在重点部分,子签名的概念不再宽容。


当我将其更改为<T> T[] toArray(T[] a);时,我得到一条警告,说明声明的类型参数T正在将其隐藏在封闭的类中,但是将名称更改为T1会使走开。

关于为什么签名如此,一种解释是,您想使用超类型数组来收集列表的元素。例如:

class A {}
class B extends A {}

List<B> list = ...
A[] elements = list.toArray(new A[0]); // should still work, no need to pass a `B[]` strictly.