简体   繁体   English

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

[英]Java get generic type that represents class from class instance

I am able to declare class like this: 我可以像这样声明类:

class TestClass<K extends TestClass<K>> {

}

I need a method returning K type: 我需要一个返回K类型的方法:

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

    }
}

If I return class instance: 如果我返回类实例:

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

I have an error about incompatible types. 我有关于不兼容类型的错误。

Sure, I can do cast: 当然,我可以做演员:

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

But in such a case I have warning about unchecked cast. 但在这种情况下,我发出了关于未经检查的演员的警告。

Is there a way to do that without warning supression? 有没有办法在没有警告抑制的情况下做到这一点?

EDIT. 编辑。 What I really want to do - to have these 2 classes: 我真正想做的事 - 拥有这两个课程:

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);
    }
}

and

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

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

I want each concrete ViewModel know about a corresponding concrete ViewHolder, and each concrete ViewHolder know about corresponding concrete ViewModel. 我希望每个具体的ViewModel都知道一个相应的具体ViewHolder,并且每个具体的ViewHolder都知道相应的具体ViewModel。

That's why I want to have such structure. 这就是为什么我想拥有这样的结构。
Actually, I didn't find another way to tell BaseModel about holder rather than above. 实际上,我没有找到另一种方式告诉BaseModel持有者而不是上面。

Declaring a class with generics like that doesn't make that class an instance of K. You are not extending K. Your cast is not only unchecked but it is wrong. 用这样的泛型声明一个类不会使该类成为K的实例。你没有扩展K.你的演员不仅没有被选中,而且是错误的。

Consider the example: 考虑这个例子:

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;
    }
}

This results into a runtime exception: 这导致运行时异常:

Exception in thread "main" java.lang.ClassCastException: TestClass cannot be cast to AnotherClass 线程“main”中的异常java.lang.ClassCastException:TestClass无法强制转换为AnotherClass

Basically when you cast (K) this you are casting an object of type TestClass to an object which extending TestClass. 基本上当你强制转换cast (K)时,你cast (K)一个TestClass类型的对象转换为一个扩展TestClass的对象。 The other way around it is true - K is a TestClass but TestClass is not a K. 另一种方式是真的--K是TestClass但是TestClass不是K.

EDIT: 编辑:

I saw your problem but still that cast is not alright. 我看到了你的问题,但仍然是演员阵容不正常。 You don't know what implementation/subclass of BaseViewHolder you will get and generics when used like that point to a specific type. 你不知道你将获得什么样的BaseViewHolder实现/子类,以及在使用时指向特定类型的泛型。 K is a child of BaseViewHolder and casting any BaseViewHolder to K which is a specific subclass is not alright. K是BaseViewHolder的子代,并将任何BaseViewHolder强制转换为K,这是一个特定的子类是不正常的。

Why don't you just make it like: 你为什么不这样做:

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);
    }
}

I cannot see any reason to use generics in your case. 在你的案例中,我看不出任何使用泛型的理由。 Making it like that you can extend BaseViewHolder and BaseViewModel and use the subclasses as instances of the base classes without any issues. 使它成为可以扩展BaseViewHolder和BaseViewModel并使用子类作为基类的实例而没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM