Java从类实例中获取表示类的泛型类型

标签 java generics

我可以这样声明类:

class TestClass<K extends TestClass<K>> {

}

我需要一个返回 K 类型的方法:

class TestClass<K extends TestClass<K>> {
    K getK() {

    }
}

如果我返回类实例:

class TestClass<K extends TestClass<K>> {
    K getK() {
        return this;
    }
}

我有一个关于不兼容类型的错误。

当然,我可以做 Actor :

class TestClass<K extends TestClass<K>> {
    K getK() {
        return (K) this;
    }
}

但在这种情况下,我会对未经检查的转换发出警告。

有没有办法在没有警告抑制的情况下做到这一点?

编辑。 我真正想做的 - 拥有这两个类(class):

class BaseViewHolder<T extends BaseViewHolder<T, K>, K extends BaseViewModel<T, K>> {
    K model;

    void setModel(K model) {
        this.model = model;
        model.setHolder((T) this);
    }
}

class BaseViewModel<T extends BaseViewHolder<T, K>, K extends BaseViewModel<T, K>> {
    T holder;

    void setHolder(T holder) {
        this.holder = holder;
    }
}

我希望每个具体的 ViewModel 都知道相应的具体 ViewHolder,并且每个具体的 ViewHolder 都知道相应的具体 ViewModel。

这就是为什么我想要这样的结构。
其实我没有找到其他方式告诉BaseModel关于holder而不是上面。

最佳答案

用这样的泛型声明一个类不会使该类成为 K 的实例。您没有扩展 K。您的转换不仅未经检查而且是错误的。

考虑这个例子:

public static void main(String[] args) throws InterruptedException {
        new TestClass<AnotherClass>().getK().get0();        
    }

class AnotherClass extends TestClass<AnotherClass>{
    int get0() {
        return 0;
    }   
}

class TestClass<K extends TestClass<K>> {
    K getK() {
        return (K)this;
    }
}

这会导致运行时异常:

Exception in thread "main" java.lang.ClassCastException: TestClass cannot be cast to AnotherClass

基本上,当您cast (K) this 时,您将类型为TestClass 的对象转换为扩展TestClass 的对象。反之亦然——K 是一个 TestClass 但 TestClass 不是 K。

编辑:

我看到了你的问题,但类型转换仍然不对。您不知道您将获得什么 BaseViewHolder 的实现/子类,以及在使用时指向特定类型的泛型。 K 是 BaseViewHolder 的子类,将任何 BaseViewHolder 强制转换为特定子类的 K 是不行的。

你为什么不让它像这样:

class BaseViewModel {
    BaseViewHolder  holder;


   //You can call this setter with any subclass of BaseViewHolder  without casting!
    void setHolder(BaseViewHolder  holder) {
        this.holder = holder;
    }
}


class BaseViewHolder {
    BaseViewModel model;

   //You can call this setter with any subclass of BaseViewModel without casting!
    void setModel(BaseViewModel  model) {  
        this.model = model;
        model.setHolder( this);
    }
}

我看不出有任何理由在您的案例中使用泛型。这样您就可以扩展 BaseViewHolder 和 BaseViewModel 并将子类用作基类的实例,而不会出现任何问题。

关于Java从类实例中获取表示类的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50269653/

相关文章:

java - 泛型未经检查的警告转换

java - 在Kotlin中结合反射、枚举和泛型,类型推断失败,但我也不知道

java - 重新定义/ rebase native 方法

java - 测试方法的返回类型是否为数字?

c# - 使用泛型和 'new' 修饰符隐藏父成员时的 C# 继承问题

generics - TypeScript 中的关联类型

Java 泛型 : Wildcard capture misunderstanding

Java-如何将数字字符串转换为字母数组

Java @FinalArgs 注释 - 如何?

java - JTree 通过单击行上的任意位置来选择节点