[java] Java 어노테이션 멤버에 어떤 유형을 사용할 수 있습니까?

오늘 이 문서에 따라 첫 번째 주석 인터페이스를 만들고 싶었고이 컴파일러 오류가 발생했습니다.

Invalid type for annotation member":
public @interface MyAnnotation {
    Object myParameter;
    ^^^^^^
}

분명히 Object주석 멤버의 유형으로 사용할 수 없습니다. 불행히도 나는 일반적으로 사용할 수있는 유형에 대한 정보를 찾을 수 없었습니다.

이것은 시행 착오를 사용하여 알게되었습니다.

  • String → 유효
  • int → 유효
  • Integer → 유효하지 않음 (놀랍게도)
  • String[] → 유효 (놀랍게도)
  • Object → 무효

아마도 어떤 유형이 실제로 허용되는지, 왜 그런지 누군가가 밝힐 수 있습니다.



답변

JLS 섹션 9.6.1에 의해 지정됩니다 . 주석 멤버 유형은 다음 중 하나 여야합니다.

  • 원어
  • 열거 형
  • 다른 주석
  • 수업
  • 위의 배열

그것은 제한적으로 보이지만 의심 할 여지가 없습니다.

또한 다차원 배열 (예 String[][]:)은 위 규칙에 의해 암시 적으로 금지됩니다.

이 답변에 설명 된대로 클래스 배열은 허용되지 않습니다 .


답변

사용 가능한 유형에 대해서는 Skaffman에 동의합니다.

추가 제한 사항 : 컴파일 타임 상수 여야합니다 .

예를 들어, 다음은 금지되어 있습니다.

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())


답변

또한 주석 자체가 주석 정의의 일부가 될 수 있음을 잊지 마십시오 . 이를 통해 간단한 주석 중첩이 가능합니다. 하나의 주석을 여러 번 제시하려는 경우에 유용합니다.

예를 들면 다음과 같습니다.

@ComplexAnnotation({
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3)
})
public Object foo() {...}

SimpleAnnotation이다

@Target(ElementType.METHOD)
public @interface SimpleAnnotation {
    public String a();
    public int b();
)

ComplexAnnotation이다

@Target(ElementType.METHOD)
public @interface ComplexAnnotation {
    public SimpleAnnotation[] value() default {};
)

예 : http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(원래 URL : https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations )


답변

주석의 개념은 주석에 복잡한 데이터 유형을 가질 수 없다는 것을 깨달을 때까지 프로젝트 디자인에 매우 적합합니다. 그 클래스의 인스턴스화 된 객체 대신 인스턴스화하려는 클래스를 사용하여 문제를 해결했습니다. 완벽하지는 않지만 Java는 거의 없습니다.

@interface Decorated { Class<? extends PropertyDecorator> decorator() }

interface PropertyDecorator { String decorate(String value) }

class TitleCaseDecorator implements PropertyDecorator {
    String decorate(String value)
}

class Person {
    @Decorated(decorator = TitleCaseDecorator.class)
    String name
}


답변