Reputation: 229
OK, be nice.
Here's an enum that implements an interface with a method that returns a 'raw type' which gives me a warning on the getCaste()
method in the interface.
public enum Thing implements HasCaste {
Type1 {
@Override
public Class getCaste() {
return String.class;
}
};
}
interface HasCaste {
public Class getCaste();
}
If I change the interface's method to:
public <T> Class<T> getCaste();
it changes to an unchecked warning on Type1
's method signature. If I then change Type1.getCaste()
's signature to:
public <T> Class<T> getCaste()
then the return has an incompatible types error because Class<String>
can't be converted to Class<T>
. If I then change the return to (Class<T>) String.class
, we get an unchecked cast warning.
Is there a way to do this without a warning?
EDIT:
Sorry I didn't add this in earlier, but it'd be good to do this:
, Type2 {
@Override
public Class getCaste() {
return Integer.class;
}
};
Upvotes: 3
Views: 5221
Reputation: 81539
As it was determined in the question I asked a while ago that was linked by Radiodef, you cannot do that with an enum
, only by a simulated enum that's actually a class, like this.
public abstract class Thing<T> implements HasCaste<T> {
public static final Thing<String> Type1 = new Thing<String>() {
@Override
public Class<String> getCaste() {
return String.class;
}
};
public static final Thing<Integer> Type2 = new Thing<Integer>() {
@Override
public Class<Integer> getCaste() {
return Integer.class;
}
};
private Thing() {
}
}
As you can see, that is not an enum
though. It is not possible with a mere enum
, because enums cannot have type parameters.
p.s.: If you found this helpful, please look at Radiodef's answer for a more complete explanation, I learned this from him, after all :)
Upvotes: 2
Reputation: 109557
Assuming you want to define several differently "typed" enum constants, then one could do:
interface HasCaste {
public Class<?> getCaste();
}
public enum Thing implements HasCaste<?> {
Type1(String.class),
Type2(Integer.class);
public final Class<?> clazz;
private Thing(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public Class<?> getCaste() {
return clazz;
}
}
One then delays the typing to the future usage of getCaste. The main characteristic of an enum is a closed value domain; one has to list all possible values inside the class.
Upvotes: 1
Reputation: 82461
You could just leave the type parameter of the returned class unspecified:
public enum Thing implements HasCaste {
Type1 {
@Override
public Class<String> getCaste() {
return String.class;
}
}, Type2 {
@Override
public Class<Integer> getCaste() {
return Integer.class;
}
};
}
interface HasCaste {
public Class<?> getCaste();
}
Upvotes: 2