Generics and Class<? extends Enum<?>>, EnumSet.allOf(class) vs class.getEnumConstants()

后端 未结 2 1372
無奈伤痛
無奈伤痛 2021-02-19 13:11

I have the following BeanValidation code that works fine, and permits to validate that a bean annotated with:

  @EnumValue(enumClass = MyTestEnum.class)
  privat         


        
2条回答
  •  情歌与酒
    2021-02-19 13:55

    My explanation on @assylias's solution:

    What we want to express about the type of the class is that it's a

    Class, for some E, that E <: Enum
    

    but Java does not allow us to introduce a type variable E in a method body.

    Usually, we can exploit wildcard and wildcard capture to introduce a hidden type variable

    class G { ... }  // b(T) is a type expression that may contain T
    
    G   --capture-->   G, for some T, that T <: A & b(T)
    

    But this won't work in our case, since T in Class does not have a bound that makes it work.

    So we need to introduce a new type with the desired bound

    class EnumClass>   // called EnumValue in assylias's solution
    
        EnumClass(Class enumClass) 
    
        Class enumClass()
    
    EnumClass   --capture-->    EnumClass, for some E, that E <: Enum
    

    We then call EnumClass.enumClass() to yield a

    Class, for some E, that E <: Enum
    

    which is the goal we've been trying to achieve.

    But how can we call the constructor of EnumClass? The origin of the problem is that we don't have a proper type for enumClass, yet the constructor of EnumClass wants a properly typed enumClass.

    Class enumClass = ...;
    new EnumClass<...>(enumClass);  // wont work
    

    Fortunately(?) the raw type helps here which disables generics type checking

    EnumClass raw = new EnumClass(enumClass);  // no generics
    EnumClass wild = raw; 
    

    So the minimum gymnastics we need to perform to cast the class to the desired type is

    ((EnumClass)new EnumClass(enumClass)).enumClass()
    

提交回复
热议问题