How to declare a Class object such that is is an Enum AND an Interface in Java

Go To StackoverFlow.com

3

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)

2012-04-05 22:41
by Appak
http://stackoverflow.com/questions/745756/java-generics-wildcarding-with-multiple-classe - Andrew T Finnell 2012-04-05 22:49


2

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

2012-04-05 22:53
by Christian Semrau
'You can not declare a local variable with an intersection type.' This isn't true, see my answer - darrengorman 2012-04-05 23:06
@milkplusvellocet It should read 'You can not declare a local variable with an intersection type directly - Andrew T Finnell 2012-04-05 23:16
Yep, that's true - darrengorman 2012-04-05 23:25
Indeed. I edited my answer - Christian Semrau 2012-04-06 08:12
Thanks that linked question does help clarify why it is not possible - Appak 2012-04-06 14:44


2

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.

2012-04-05 22:51
by darrengorman
Thanks for your answer but I don't think that will work for me. I mistyped local should have been member variable. I have updated my question - Appak 2012-04-06 14:32
No problem but I still don't understand what you were asking. 'The return values of its operations will change depending on which enum it is given.' Why couldn't you achieve this using a parameterised MyClass - darrengorman 2012-04-06 15:26
Ads