Question

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.

Was it helpful?

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

OTHER TIPS

You most certainly means

Class<? extends Blah> interfaceType;

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

Update

If the Dummy class can't be modified, then it is pretty dubius WHY there is such a setter method. But anyway, you may avoid the "generic type" check, by casting your argument to Class (without type argument), as in: dummyObj.setInterfaceType( (Class) Inter.class )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top