abstract class AbsClass {}

class MyAbs extends AbsClass {}

class MyClass<S extends AbsClass> {
    S getObj() {
        return new MyAbs();
    }
}

取得编译器问题:



正确的方法是什么?

编辑:
我希望能够初始化MyClass {MyAbs},然后调用getObj(),这将返回我一个MyAbs对象。有了Andy的回答,我将不得不将AbsClass强制转换为MyAbs或MySecondAbs,这是我要避免的事情

最佳答案

安迪(Andy)描述了如何解决该问题,我将尽力解释原因。

不能保证S可以分配给MyAbs,而不能分配给AbsClass,并且每个实例都将指定AbsClass的子类。

考虑:

class MyOtherAbs extends AbsClass {}

MyClass myClass = new MyClass<MyOtherAbsClass>{};

这将与您所拥有的相冲突。

更新:

根据您的评论,您似乎想要实现上述目标。挑战是如果MyOtherAbs具有带参数的构造函数怎么办?或被实现为Singleton(即私有(private)构造函数和静态getInstance())。简而言之,没有保证可以统一的方式来构造它们。此外,由于类型擦除,在运行时,S的概念消失了,因此您无法执行以下操作:
return new S();

您基本上有两种选择,一种是使用子类化:
public interface AbsClassFactory<S extends AbsClass>{ //takes the place of MyClass
    public S getInstance();
}

MyAbsFactory implements AbsClassFactory<MyAbs>{
    public MyAbs getInstance(){
        return new MyAbs(); //or however MyAbs is instantiated
    }
}

另一个选择是反射:
class MyClass {
    public <S extends AbsClass> S getObj(Class<S> clazz) throws InstantiationException, IllegalAccessException {
        return clazz.newInstance();
    }
}

请注意,第二个假定没有可用的arg构造函数,如果没有,则将抛出运行时异常。

10-04 13:13