I have couple of enums implementing some common interface and I would like to return class literal from the method. However I am unable to specify the intersection type correctly. See below the code sample illustrating the problem.
public class GenericsTest {
interface Iface {
}
enum E1 implements Iface {
}
enum E2 implements Iface {
}
<E extends Enum<E> & Iface> Class<E> getEnum1() {
return E1.class; //ERROR incompatible types: java.lang.Class<GenericsTest.E1> cannot be converted to java.lang.Class<E>
}
Class<? extends Enum<?>> getEnum3() {
return E1.class; //OK
}
Class<? extends Iface> getEnum4() {
return E1.class; //OK
}
<E extends Enum<E> & Iface> void enumParam(Class<E> p) {
enumParam(E1.class); //OK
}
}
#getEnum1
method doesn't compile. Interestingly it works as parameter value in #enumParam
. How can I specify the intersection type to be able to return class literal from the method?
The method getEnum1
does not compile for literally the same reason as this one:
public <E> E foo() {
return "bar"; // Compile time error: Incompatible types E and String
}
See? Just because the type parameter E
could be eventually a string, it does not mean it is compatible with String
. One could call this function as Integer i = x.<Integer>foo();
, so returning a string does not make sense here.
getEnum1
is quite the same. Type parameter E
could be choosen to be the type E1
(very bad naming here), but it does not mean E1
is always compatible with E
. Consider E2 e2 = x.<E2>getEnum1();
. You may wonder why the compiler doesn't just alert an error when one tries to call it with the wrong type parameter. The thing is, E2
satisfies the type constraints, so there is just no reason to show an error there.
Easiest (and possibly the only) way is to just get rid of generics there:
Class<E1> getEnum1() {
return E1.class;
}
If you don't want to expose the concrete type E1
here, you are out of luck. All you can do is to extract the common functionalities to an interface, and return that type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With