使用 <S extends {class}> 的 Java 泛型和不兼容类型

标签 java generics

abstract class AbsClass {}

class MyAbs extends AbsClass {}

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

获取编译器问题:

Error:(33, 16) java: incompatible types: MyAbs cannot be converted to S

正确的做法是什么?

编辑: 我希望能够初始化 MyClass{MyAbs} 然后调用 getObj() 返回一个 MyAbs 对象。根据 Andy 的回答,我必须将 AbsClass 转换为 MyAbs 或 MySecondAbs,这是我试图避免的

最佳答案

Andy 已经描述了如何解决这个问题,我将尝试解释原因。

S不保证可以分配给MyAbs,只能分配给AbsClass,每个实例都会指定一个AbsClass的子类

考虑:

class MyOtherAbs extends AbsClass {}

MyClass myClass = new MyClass<MyOtherAbsClass>{};

这会与您拥有的冲突。

更新:

根据您的评论,您似乎想要实现上述目标。挑战是如果 MyOtherAbs 有一个带参数的构造函数怎么办?或者作为单例实现(即私有(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 构造函数,如果没有则抛出运行时异常。

关于使用 <S extends {class}> 的 Java 泛型和不兼容类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40516423/

相关文章:

java.lang.NullPointerException | java.lang.NullPointerException尝试从另一个类数组获取值

java - 扩展泛型类时遇到问题

java - 为什么这种(​​错误)使用 Java 泛型的方法无法编译?

ios - 如何在 obj-c 上正确使用泛型?

java - 在两个 SQLSessionFactory bean 之一上使用 @Primary 时出现 "java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist"

java - 尝试在 Apache Kylin 中为示例数据构建多维数据集时出现 java.io.FileNotFoundException : File does not exist: hive-exec-2. 1.0.jar 错误

java - 为什么 Object.to string 对于 List 类型返回 true

c# - 比较委托(delegate) Action<T>

java - 如何将实体标记为可缓存

java - 在 Java 中提供特征的库或语言扩展?