如何在java中强制转换为CRTP?

我有一个非常简单的例子,我做了一些基本的通用赋值:

final Detail detail = field.getAnnotation(Detail.class); final String example = detail.example(); final Class type = field.getType(); if (List.class.isAssignableFrom(type)) ... else if (Enum.class.isAssignableFrom(type)) setValue(contract, field, Enum.valueOf(type, example)); else if (...) ..... 

但是Enum.valueOf()有点难以调用,在我的例子中,错误是:

java.lang.Enum中的valueOf(java.lang.Class,java.lang.String)不能应用于(java.lang.Class,java.lang.String)

这非常有意义,因为type是Class 。 但由于Enum是CRTP,我找不到一种好的方法来转换类型以使编译器满意。 是使用原始类型Enum.valueOf((Class)type, example))唯一的答案? 它给了我2个警告,而不是只有一个。

以下行只有一个警告:

 ... setValue( contract, field, Enum.valueOf( type.asSubclass( Enum.class ), example ) ); ... 

您可以编写一个辅助方法来捕获满足Enum要求的“T”类型:

 private > T helper(Class type, String example) { return Enum.valueOf((Class)type, example); } 

这应该只有一个警告

然后你可以像使用它一样

 else if (Enum.class.isAssignableFrom(type)) setValue(contract, field, helper(type, example)); 

编辑:好的,那怎么样:

 private > Object helper(Class type, String example) { return Enum.valueOf((Class)type, example); } 

我不认为删除编译器警告是可能的

最好的情况是将所有错误减少到像@tangens那样的错误。

找到两个论坛post,显示不成功的答案,并解释了为什么多一点。

所以我把一个完整的例子放在一起来展示我所看到的问题。

 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.util.List; public class Test { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Detail { String example(); } public enum ExampleEnum { FOO_BAR, HELLO_WORLD } @Detail(example = "FOO_BAR") public ExampleEnum test; public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { populate(new Test()); } public static void populate(Object o) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { final Field field = o.getClass().getField("test"); final Detail detail = field.getAnnotation(Detail.class); System.out.println("Annotation = " + detail); final String example = detail.example(); final Class type = field.getType(); System.out.println("Field Class = " + type.getName()); if (List.class.isAssignableFrom(type)) { } else if (Enum.class.isAssignableFrom(type)) { Class enumType = type.asSubclass(Enum.class); // Enum is a raw type. References to generic type Enum should be parameterized Enum val = Enum.valueOf(enumType, example); // 1) Enum is a raw type. References to generic type Enum should be parameterized // 2) Type safety: Unchecked invocation valueOf(Class, String) of the generic // method valueOf(Class, String) of type Enum field.set(o, val); } } } 
    Interesting Posts