Search code examples
javainheritanceencapsulation

Cast to super class type a "Class"


I have an interface

interface Inter extends Blah {
   public void someMethod();
}

class Dummy {
  Class<Blah> interfaceType;

  public setInterfaceType( Class<Blah> input ) {
    this.interfaceType = input;
  }  
}

class tester {
  public void init() {
    Dummy dummyObj = new DummyObj();
    dummyObj.setInterfaceType( Inter.class );     //This complains that the type is not suitable
  }
}

Compilation error:

The method setInterfaceType(Class) in the type Dummy is not applicable for the arguments (Class)

I tried casting input to Class<Blah> while calling setter but that isnt allowed either. Im not understanding why it doesnt accept a class of sub-class-type. Can anyone tell me whats happening here and how the setter can be invoked. The Dummy class is external so i cannot change it.


Solution

  • Generics are not covariant so you can't set to Class<Blah> object of type Class<Inter>. Think about it. If you would be able to use List<Fruit> list = new ArrayList<Apple>() then via list you would be able to add not only Apples but also other Fruits. Would that be OK?

    To solve this problem try changing Class<Blah> to Class<? extends Blah>

    You can also change your Dummy class to use generic type T

    class class Dummy<T extends Blah> {
        Class<T> interfaceType;
    
        public void setInterfaceType(Class<T> input) {
            this.interfaceType = input;
        }
    }
    

    and use it like

    Dummy<Inter> dummyObj = new Dummy();
    dummyObj.setInterfaceType(Inter.class);