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

青春壹個敷衍的年華 提交于 2019-12-23 16:52:28

问题


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)


回答1:


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




回答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.



来源:https://stackoverflow.com/questions/10037008/how-to-declare-a-class-object-such-that-is-is-an-enum-and-an-interface-in-jav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!