Java泛型类构造函数调用

时间:2013-11-26 13:26:16

标签: java generics constructor

我有以下代码:

public class A {}

public class B extends A {}

public class C <T extends A> {

  private final T data;

  public C(final T data) {
    this.data = data;
  }
}

public class D<T extends B> extends C<T> {

  public D(T data) {
    super(data);
  }

  public D() {
    this(new B());
  }

  public static D<B> create() {
    return new D(new B());
  }
}

D类中存在编译错误:

error: no suitable constructor found for D(B)
    this(new B());
constructor D.D() is not applicable
  (actual and formal argument lists differ in length)
constructor D.D(T) is not applicable
  (actual argument B cannot be converted to T by method invocation conversion)
where T is a type-variable:
T extends B declared in class D

令我感到困惑的是,编译基本相同的静态方法D.create()没有任何错误。谁能解释这个错误?和D()和D.create()之间的区别?

2 个答案:

答案 0 :(得分:4)

错误就在那里,因为对于课程D,不知道该类型是B,只是通用类型将扩展 B - 你假设它将是B,因为你的类层次结构中还没有其他类(编译器必须考虑的事实可能在将来发生变化)。


请注意,在工厂方法中,您要为D实例化原始类型(一个没有通用参数)。相反,提供一个类型:

你应该改变:

public static D<B> create() {
    return new D(new B());
}

为:

public static D<B> create() {
    return new D<B>(new B()); // Note: Added generic parameter <B>
}

答案 1 :(得分:1)

因为类T的泛型类型D未绑定

这将有效

public class E extends D<B> {

    public E() {
        super(new B()); // call to D's constructor public D(T data)
    }
}

通常你会以这种方式调用D的构造函数:

new D<B>(new B());

但是你不能这样做

public D() {
    this<B>(new B());
}

另一个例子。

稍微更改一下代码,您就会看到问题。

class BBB extends B {
}

class C<T extends A> {

    protected final T data;

    public C(final T data) {
        this.data = data;
    }
}

class D<T extends B> extends C<T> {

    public D() {
        this(new B());
    }

    public T getData(){
        return data;
    }
}

D<BBB> dOfBBB = new D<BBB>();
BBB data = dOfBBB.getData(); // So if this(new B()) would work 
                              // how can the data then be returned?
                              // Because BBB is returned but it would be 
                              // initialized with only a B instance