2

我有一个非常简单的案例,我做了一些基本的通用分配:

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<Object>. 但是由于Enum是 CRTP,我找不到一个好的方法来转换类型以使编译器满意。使用原始类型Enum.valueOf((Class)type, example))是唯一的答案吗?它给了我 2 个警告,而不是只有一个。

4

3 回答 3

3

以下行将只发出一个警告:

...
setValue( contract, field, Enum.valueOf( type.asSubclass( Enum.class ), example ) );
...
于 2009-09-29T21:39:22.453 回答
1

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

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

这应该只有一个警告

然后你可以像这样使用它

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

编辑:好的,那么怎么样:

private <T extends Enum<T>> Object helper(Class<?> type, String example) {
    return Enum.valueOf((Class<T>)type, example);
}
于 2009-09-22T08:53:29.163 回答
1

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

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

发现两个论坛主题显示不成功的答案,并解释了更多的原因。

因此,我整理了一个完整的示例来演示我所看到的问题。

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<? extends Enum> enumType = type.asSubclass(Enum.class); // Enum is a raw type. References to generic type Enum<E> should be parameterized
      Enum val = Enum.valueOf(enumType, example); // 1) Enum is a raw type. References to generic type Enum<E> should be parameterized
                                                  // 2) Type safety: Unchecked invocation valueOf(Class<capture#7-of ? extends Enum>, String) of the generic
                                                  //    method valueOf(Class<T>, String) of type Enum
      field.set(o, val);
    }
  }
}
于 2009-09-30T05:00:56.337 回答