处理泛型的Java代码有什么问题?

dev*_*ium 5 java generics

interface Addable<E> {
    public E add(E x);
    public E sub(E y);
    public E zero();
}

class SumSet<E extends Addable> implements Set<E> {

    private E element;

    public SumSet(E element) {
        this.element = element;
    }

    public E getSum() {
        return element.add(element.zero());
    }
}
Run Code Online (Sandbox Code Playgroud)

它似乎element.add()不会返回,E extends Addable而是一个Object.这是为什么?它与Java有什么关系,在运行时不知道对象类型到底是什么,所以它只是假定它们是对象(因此需要转换)?

谢谢

cle*_*tus 9

尝试:

class SumSet<E extends Addable<E>> implements Set<E> {
Run Code Online (Sandbox Code Playgroud)

我不知道这是不是你的意思,但基本上问题是你Addable在声明中使用的SumSet是原始类型.剥离所有通用参数类型并使其Addable看起来SumSet像:

interface Addable {
  Object add(Object x);
  Object sub(Object y);
  Object zero();
}
Run Code Online (Sandbox Code Playgroud)

显然Object不是一个E,因此错误.请参阅什么是原始类型?来自Java Generics FAQ.

对于public接口定义中的方法,侧面说明是不必要的.


Mat*_*hen 5

它应该是:

class SumSet<E extends Addable<E>> implements Set<E> {
Run Code Online (Sandbox Code Playgroud)

您的原始代码指定SumSet的每个元素必须是E的实例,即实现的类Addable(相当于Addable<Object>).通过更改AddableAddable<E>,您将指定E类的add,sub和zero方法必须接受并返回E的实例(而不仅仅是Object).

请注意,SumSet中的E类型变量与上述E变量无关.所以:

class SumSet<T extends Addable<T>> implements Set<T> {

    private T element;

    public SumSet(T element) {
        this.element = element;
    }

    public T getSum() {
        return element.add(element.zero());
    }
}
Run Code Online (Sandbox Code Playgroud)

工作得很好.