Java generics & incompatible types using <S extends {class}>

abstract class AbsClass {}

class MyAbs extends AbsClass {}

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

Getting the compiler:

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

What is the right way to do this?

Edit: I was hoping I could install MyClass {MyAbs} and then call getObj (), which would return the MyAbs object to me. With Andy's answer, I would have to drop AbsClass to MyAbs or MySecondAbs, which I tried to avoid

+4
source share
3 answers

Andy told how to fix this problem, I will try to explain why.

Scannot be assigned MyAbs, only until AbsClass, and each instance will indicate a subclass AbsClass.

Consider:

class MyOtherAbs extends AbsClass {}

MyClass myClass = new MyClass<MyOtherAbsClass>{};

, .

UPDATE:

, , . , , MyOtherAbs ? Singleton (.. 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 , .

+5

S extends MyAbs, . S MyAbs, MyAbs .

, , .

+3

From your comment, it seems that you can accomplish the same thing using the interface Supplier:

Supplier<MyAbs> supp = MyAbs::new; // Constructor reference
MyAbs obj = supp.get();

Supplier<MySecondAbs> supp2 = MySecondAbs::new;
MySecondAbs obj2 = supp2.get();
+1
source

Source: https://habr.com/ru/post/1660346/


All Articles