문제

기본 일반 과제를 수행하는 매우 간단한 사례가 있습니다.

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)에 적용 할 수 없습니다.

이것은 유형이 있기 때문에 완벽하게 의미가 있습니다 Class<Object>. 하지만 그때부터 Enum CRTP입니다. 컴파일러를 행복하게 만들기 위해 유형을 캐스트하는 좋은 방법을 찾을 수 없습니다. 원시 유형을 사용하고 있습니다 Enum.valueOf((Class)type, example)) 유일한 대답? 그것은 단 하나 대신 2 개의 경고를 제공합니다.

도움이 되었습니까?

해결책

다음 줄은 하나의 경고만으로 수행합니다.

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

다른 팁

열거의 요구 사항을 충족시키는 "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);
}

컴파일러 경고를 제거 할 수 없다고 생각합니다.

가장 좋은 시나리오는 모든 오류를 @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);
    }
  }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top