类必须声明为抽象或实现抽象方法toArray。

4
我有一个类叫做Foo,它扩展了AbstractList并实现了List接口。该类实现了一些List方法,但有一些只是抛出了UnsupportedOperationException异常。

toArray方法就是其中之一,尽管编译器不会抱怨其他未真正实现的方法,但它会抱怨toArray方法,报错如下:

Class must either be declared abstract or implement abstract method toArray(T[]) in List.

public class Foo extends AbstractList implementst List  {
    ...
     public <T> T[] toArray(T[] a) throws UnsupportedOperationException {
        throw new UnsupportedOperationException(error);
    }
}

这里出了什么问题,为什么编译器仍然认为toArray(T[])方法未被实现?

toArray 方法已经在 AbstractCollection 中实现,而 AbstractList 继承了它。 - xehpuk
2个回答

2

由于您正在使用通用方法 public T[] toArray(T[] a),因此您应该向类签名添加参数并使其分别扩展和实现参数化的类和接口,而不是原始的类和接口。然后它将编译:

public class Foo<T> extends AbstractList<T> implements List<T> {

    @Override
    public <E> E[] toArray(E[] a) throws UnsupportedOperationException {
        throw new UnsupportedOperationException("Error!");
    }

    ...
}

同意。已编辑答案。这样就不会有隐藏警告了。 - Gyrotank
@azurefrog 我没有在和你说话。 - xehpuk
1
这有点不清楚 - OP的代码已经在方法签名中有一个参数。 - Oliver Charlesworth
抱歉,我本意是写“类签名”,而不是“方法”。已进行编辑。 - Gyrotank
java.util.Collection 实际上是一个参数化接口:public interface Collection<E> extends Iterable<E>。它的所有子类也都是参数化的。你可以使用原始版本,将其内容视为对象(这是为了与 Java 5 之前的类兼容而需要的),但是如果要重写参数化方法,则需要使你的类也成为参数化的。 - Gyrotank
如果你这样写:public class Foo extends AbstractList implements List { public <E> E[] toArray(E[] a) throws UnsupportedOperationException {...},你会得到一个错误:"Name clash: The method toArray(E[]) of type Foo has the same erasure as toArray(Object[]) of type AbstractCollection but does not override it"。这里有解释:https://dev59.com/m1_Va4cB1Zd3GeqPPARz。 - Gyrotank

-1

这段代码可以编译:

import java.util.AbstractList;
import java.util.List;

public class Foo extends AbstractList implements List  {

    @Override
    public Object[] toArray(Object[] a) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object get(int index) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int size() {
        // TODO Auto-generated method stub
        return 0;
    }
}

如果您使用java.util包。

3
好的,但为什么不使用 <T> T[] toArray(T[] a) 方法呢? - Oliver Charlesworth
因为超类和子类中的参数类型不能不同。这里是https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html。 - Jay Smith
我不确定那个链接的相关性 - 它只是在说例如SomeClass<Derived>不是SomeClass<Base>的子类型。 - Oliver Charlesworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接