English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 애노테이션 Annotation 해석

개요

       Java에서1.5설명 Annotation을 도입하였습니다. Java 표시기 또는 Java 설명으로 알려져 있으며, 설명은 원본 코드에 직접 사용할 수 있는 문법 메타데이터입니다./메서드/변수/매개변수/패키지 이름 등은 설명을 받을 수 있습니다. Javadoc 태그와 달리, 컴파일러는 class 파일 생성 시 설명 코드를 유지하며, 또한 실행 중에 사용할 수 있습니다.-time) 설명을 사용할 수 있습니다. Java 가상 머신은 설명을 유지하며, 이를 통해 설명 Annotation의 관련 정보를 반영할 수 있습니다.

내장 설명

실제로 우리는 일상에서 어노테이션을 자주 만나게 됩니다. 예를 들어 @Override, @Deprecated와 같은 어노테이션들도 JDK에 내장된 어노테이션들입니다. 먼저 Java 내장 어노테이션 중 주요한 것들을 살펴보겠습니다.
 •Java 코드에 작용하는 어노테이션
◦@Override는 특정 메서드가 재정의된 메서드인지 확인합니다. 이 메서드가 부모 클래스나 구현된 인터페이스에서 찾지 못하면 컴파일 과정에서 오류가 발생합니다
 ◦@Deprecated는 특정 메서드나 클래스가 폐지되었음을 표시합니다. 이 클래스나 메서드를 사용하면 컴파일 과정에서 경고가 발생합니다
 ◦@SuppressWarnings는 컴파일러에 표시된 매개변수에 대한 경고를 무시하도록通知합니다
 ◦@SafeVarargs는 타입 파라미터를 가진 메서드나 생성자 호출에 대한 경고를 무시합니다1.7New annotation
 ◦@FunctionalInterface 표시된 인터페이스가 기능적 인터페이스로 사용될 것임을 나타냅니다1.8New annotation

•다른 어노테이션에 대한 어노테이션을 메타 어노테이션(Meta Annotation)이라고 합니다
◦@Retention 표시된 어노테이션의 사용 시간(어노테이션이 언제 사용될 것인지)을 나타냅니다
■ 단지 소스 코드에 남겨져 컴파일 과정에서 버려집니다 (RetentionPolicy.RUNTIME)
 ■ 어노테이션은 컴파일 과정에서 클래스 파일에 저장되며, 클래스 파일이 로드될 때 무시됩니다 (RetentionPolicy.CLASS)
 ■ 어노테이션은 클래스 파일 로드 시 읽혀지며, 즉 실행 중 어노테이션은 사용 가능하며, 반영을 통해 어노테이션 정보를 얻을 수 있습니다 (RetentionPolicy.RUNTIME)

 ◦@Documented 표시된 어노테이션은 Javadoc 생성 시 Javadoc 문서에 기록됩니다
 ◦@Target 표시된 어노테이션의 작용 범위를 나타냅니다
■ElementType.TYPE: 클래스, 인터페이스(어노테이션 타입 포함) 또는 enum 선언을 설명하는 데 사용됨
 ■ElementType.FIELD: 필드를 설명하는 데 사용됨
 ■ElementType.METHOD: 메서드를 설명하는 데 사용됨
 ■ElementType.PARAMETER: 매개변수를 설명하는 데 사용됨
 ■ElementType.CONSTRUCTOR: 생성자를 설명하는 데 사용됨
 ■ElementType.LOCAL_VARIABLE: 지역 변수를 설명하는 데 사용됨
 ■ElementType.ANNOTATION_TYPE: 어노테이션을 설명하는 데 사용됨
 ■ElementType.PACKAGE: 패키지를 설명하는 데 사용됨

 ◦@Inherited 표시된 어노테이션은 상속되는 어노테이션임을 나타냅니다. 즉, @Inherited로修饰된 어노테이션 타입이 클래스에 사용되면, 이 어노테이션도 해당 클래스의 자식 클래스에 적용됩니다.
 ◦@Repeatable indicates that the annotated annotation can be applied multiple times to the same object,1.9New annotation

 Custom annotation

As mentioned above, many annotations have been discussed. Everyone should focus on meta-annotations, and we often use meta-annotations to assist us when defining custom annotations. The format of a custom annotation is public @interface annotation_name {body}, and when using @interface to define a custom annotation, it automatically inherits the java.lang.annotation.Annotation interface. When defining a custom annotation, you cannot inherit other annotations or interfaces. The methods declared in the annotation are actually declared as annotation parameters, the name of the method is the name of the parameter, the return type is the type of the parameter, and the default value can be declared through default.

Custom annotations are simple, using @interface to define an annotation, as follows.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ClassInfo {
 String author() default "Wang";
 String date();
 String comments();
}

A custom annotation named ClassInfo has been defined. According to @Retention, it can be known that this annotation will always exist, that is, it is still valid during the program's execution; @Target(ElementType.TYPE) indicates that the ClassInfo annotation is used for class, interface, or enum declarations; @Documented
It explains that ClassInfo information can be written into the Javadoc document.

Let's take a look at some annotation parameters in the custom annotation, which contains three annotation parameters. Annotation parameters can be set with default values, for example, the author annotation parameter has a default value of Wang, and the other two parameters do not have default values.

Let's take a look at another custom annotation.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodInfo {
 String description() default "No Description";
 String date();
}

This custom annotation MethodInfo is used for methods, and it also exists during the program's execution; it contains two annotation parameters.

Annotation parameter definition (method definition), can only be used with public or default two access modifiers, and the parameter type supports the following types.
 •eight basic data types (byte, int, short, long, float, double, char, boolean);
 •String 타입
 •Class 타입
 •enum 타입
 •Annotation 타입
 •이 모든 타입의 배열

注解의 사용

위 두 가지 注解 외에 Field 범위의 注解을 추가했습니다.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldInfo {
 String type();
 String name();
}

사용자 정의된 注解의 파라미터가 기본 값이 지정되지 않았다면, 사용자 정의된 注解을 사용할 때 이러한 파라미터에 값을 할당해야 합니다. 그렇지 않으면 컴파일러가 오류를 발생시킵니다.

注解사용의 코드를 확인해 보겠습니다:

@ClassInfo(author = "wang",
  date = "2016/9/13"
  comments = "annotation demo")
public class AnnotationDemo {
 @FieldInfo(type = "public", name = "firstField")
 public int firstField;
 @FieldInfo(type = "private", name = "secondField")
 private String secondField;
 @MethodInfo(description = "AnnotationDemo에 있는 메서드", name = "firstMethod")
 public void firstMethod(String value) {
  System.out.printf("first method involved");
 }
 @MethodInfo(description = "AnnotationDemo에 있는 메서드", name="secondMethod")
 private void secondMethod() {
  System.out.printf("first method involved");
 }
}

注解정보를 얻기

注解정보를 얻으려면, 먼저 프로그램 실행 중에 있는지 확인해야 합니다. 따라서 일반적으로 사용자 정의된 注解에 @Retention(RetentionPolicy.RUNTIME) 메타정의를 추가합니다. 이렇게 하면 프로그램 실행 중에 반사를 통해 일부 注解정보를 얻을 수 있습니다. 반사에 대한 설명은 이 글을 참조하세요.

public class AnnotationTest {}}
 public static void main(String[] args) {
  resolveClassAnnotationInfo(AnnotationDemo.class);
  resolveFieldAnnotationInfo(AnnotationDemo.class);
  resolveMethodAnnotationInfo(AnnotationDemo.class);
 }
 private static void resolveClassAnnotationInfo(Class<?> clz) {
  // 해당 클래스에 ClassInfo 어노테이션이 있는지�断
  if(clz.isAnnotationPresent(ClassInfo.class)) {
   ClassInfo classInfo = (ClassInfo) clz.getAnnotation(ClassInfo.class);
   System.out.println(classInfo.author()) + " " + classInfo.comments() + " " + classInfo.date());
  }
 }
 private static void resolveFieldAnnotationInfo(Class<?> clz) {
  Field[] fields = clz.getDeclaredFields();
  for (Field field : fields) {
   if(field.isAnnotationPresent(FieldInfo.class)) {
    FieldInfo fieldInfo = (FieldInfo) field.getAnnotation(FieldInfo.class);
    System.out.println(fieldInfo.type()) + " " + fieldInfo.name());
   }
  }
 }
 private static void resolveMethodAnnotationInfo(Class<?> clz) {
  Method[] methods = clz.getDeclaredMethods();
  for (Method method : methods) {}}
   if(method.isAnnotationPresent(MethodInfo.class)) {
    MethodInfo methodInfo = (MethodInfo) method.getAnnotation(MethodInfo.class);
    System.out.println(methodInfo.name() + " " + methodInfo.description());
   }
  }
 }
}

클래스 내의 Field을 반사를 통해 가져옵니다/Method 등을 getAnnotation() 또는 getAnnotations()를 통해 관련 애너테이션을 가져와서, 특정 애너테이션을 얻으면 특정 정보를 가져올 수 있습니다.

실행 결과 출력은 다음과 같습니다:


그림-1 실행 결과 그림

정리

Java의 초보자나 일정한 경험을 가진 Java 개발자라면, Java 애너테이션에 대한 접근이 적을 수 있으며, 실제로는 애너테이션을 많이 사용하지 않지만, 코드에서 자주 볼 수 있습니다. 이 문서는 애너테이션에 대한 간단한 소개이며, 코드 수준에서는 읽기에 무리가 없습니다.

이것이 이 문서의 전체 내용입니다. 많은 도움이 되길 바랍니다. 또한, 나아가 힘을 주는 강의에 많이 지지해 주시기 바랍니다.

선언: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자의 소유물입니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공 편집 처리를 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 침해가 의심되는 내용이 있으시면, 이메일을 notice#w로 보내 주시기 바랍니다.3codebox.com(이메일을 보내는 경우, #을 @으로 변경하십시오. 신고를 하고 관련 증거를 제공하시면, 사이트는 즉시 저작권 침해 내용을 삭제합니다.)

추천해드립니다