Java 列表<;T>;覆盖toArray最终为T1[]toArray

Java 列表<;T>;覆盖toArray最终为T1[]toArray,java,android,Java,Android,我试图通过在类中实现List接口来稍微调整列表 我可以毫无问题地重写和实现所有方法,除了这个: <T> T[] toArray(T[] a); 当将鼠标悬停在a参数上时,我看到此lint警告: 应为java.lang.Object类型的数组 当我试图手动将其更改回T[]而不是T1[]时,我得到以下错误: “QueryList”中的toArray(T[])与“java.util.List”中的“toArray(T[])冲突;两种方法具有相同的擦除,但都不重写另一种方法 这是Andro

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

我可以毫无问题地重写和实现所有方法,除了这个:

<T> T[] toArray(T[] a);
当将鼠标悬停在
a
参数上时,我看到此lint警告:

应为
java.lang.Object
类型的数组

当我试图手动将其更改回
T[]
而不是
T1[]
时,我得到以下错误:

“QueryList”中的toArray(T[])与“java.util.List”中的“toArray(T[])冲突;两种方法具有相同的擦除,但都不重写另一种方法

这是Android Studio/intelliJ中的一个bug,它无法正确创建覆盖,还是我遗漏了什么

编辑: 下面是类的声明,包括
T
及其使用位置

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>
public类QueryList实现列表{
//
受保护的最终清单;
公共查询列表(){
内部=新的ArrayList();
}
公共查询列表(int initialCapacity){
内部=新阵列列表(初始容量);
}
公共查询列表(@NonNull集合)
没有其他的问题

您的
QueryList
类声明了一个类型参数,该参数也被命名为
T
,因此intellij可能会将覆盖中的参数重命名为
T1
,以明确显示它是不同的

请注意,在
列表中
还声明了它自己的类型参数,这也是正确重写所必需的:

<T> T[] toArray(T[] a);
^^^
但这将不再使其成为覆盖,因为类型参数必须匹配。根据:

在类C中声明或由类C继承的实例方法mC重写了在类A中声明的另一个方法mA,如果以下所有条件均为真:

  • mC的签名是mA签名的子签名
8.4.2
中:

如果两个方法或构造函数M和N具有相同的名称,相同的类型参数(如果有),则它们具有相同的签名,并且在将N的形式参数类型调整为M的类型参数后,具有相同的形式参数类型

在重点部分,次签名的概念也不再宽松


当我将其更改为
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.
class A{}
类B扩展了{}
列表=。。。
A[]elements=list.toArray(新的A[0]);//应该仍然可以工作,不需要严格地传递A`B[]`。

请向我们展示
内部
的声明。谢谢。
受保护的最终内部列表;
和构造函数中实例为
新数组列表();
我猜您在一个封闭类中有另一个类型参数,该类也被命名为
T
?@jornverne请查看我在上面的编辑。我发布了类声明和构造函数。不涉及其他T,不涉及其他重写。@Grisgram“不涉及其他T”您的
QueryList
类声明了一个类型参数,该参数也被命名为
T
,因此intellij可能会将覆盖中的参数重命名为
T1
,以显式显示它是不同的。是的。例如,如果您检查
java.util.ArrayList
,您将看到类类型参数是
E
ArrayList实现List
),但特定于此
T[]toArray(T[]a)
方法。还有
Object[]toArray()
方法,但没有
E[]toArray()
非常感谢您的快速回复!
T[] toArray(T[] a);
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.