I have a utility class that needs to work on a generic Class but must be restricted to those that are an enum and implement a particular interface.
// These two work
Class<? extends Enum<?>> enumClass;
Class<? extends MyInterface> interfaceClass;
// This is what I want but does not work
Class<? extends MyInterface & Enum<?>> enumAndInterfaceClass;
For generics I can successfully use this
public class MyClass<T extends Enum<T> & MyInterface> {
public MyClass(Class<T> theClass) {
...
}
}
However I can't use the Generics everywhere and need to declare it separately. I am not sure if this is even possible.
So my question boils down to how can I declare a member variable with those constraints?
So Currently MyClass is a singleton then as needed the enum/interface can be updated. The return values of its operations will change depending on which enum it is given. I would like to not have the generics on it since that would require creating a new instance for every change to the enum. There is a lot of code using it already so deviating from the singleton is not going to be approved. So a reference must be kept. I suppose I could only enforce the Interface requirement then check in the setter method that it is an enum throwing an exception otherwise but that is not ideal.
Edit (Updated question and added more detail)
As far as I remember, you can only declare intersection types (this is what &
creates) for type parameters of classes and methods. You can not declare a local variable with an intersection type directly; you can create such variables with the aid of a class or method type parameter, as seen in the answer of milkplusvellocet.
See the JLS reference in this answer to a similar question: https://stackoverflow.com/a/6643378/282229
This should work:
public interface MyInterface {
void foo();
}
public final class Utils {
public static <E extends Enum<E> & MyInterface> void doWork(Class<E> clazz) {
for(E enumConstant : clazz.getEnumConstants) {
enumConstant.foo();
}
}
}
EDIT I didn't notice your line about using the captured type as a local variable. You can of course use this throughout the body of the parameterised method, see revised snippet above.
MyClass
- darrengorman 2012-04-06 15:26