[java] @Override와 같은 주석은 Java에서 내부적으로 어떻게 작동합니까?

아무도 주석이 Java에서 내부적으로 어떻게 작동하는지 설명해 줄 수 있습니까?

Java에서 java.lang.annotation 라이브러리를 사용하여 사용자 지정 주석을 만드는 방법을 알고 있습니다. 하지만 여전히 내부적으로 작동하는 방식을 알 수 없습니다 (예 : @Override 주석).

자세히 설명해 주시면 정말 감사하겠습니다.



답변

어노테이션 종류의 첫 번째 주요 차이점은 컴파일 타임에 사용 된 다음 폐기 (예 🙂 @Override또는 컴파일 된 클래스 파일에 배치되고 런타임시 (예 : Spring ‘s @Component) 사용할 수 있는지 여부 입니다. 이는 주석 의 @Retention 정책에 의해 결정됩니다 . 고유 한 주석을 작성하는 경우 주석이 런타임 (자동 구성 등)에 도움이되는지 아니면 컴파일 시간에만 (검사 또는 코드 생성에) 유용한 지 결정해야합니다.

주석이 포함 된 코드를 컴파일 할 때 컴파일러는 액세스 수정 자 ( public/ private) 또는 같은 소스 요소의 다른 수정자를 보는 것처럼 주석을 봅니다 final. 어노테이션을 발견하면 특정 어노테이션에 관심이 있다고 말하는 플러그인 클래스와 같은 어노테이션 프로세서를 실행합니다. 주석 프로세서는 일반적으로 Reflection API를 사용하여 컴파일되는 요소를 검사하고 단순히 검사를 실행하거나 수정하거나 컴파일 할 새 코드를 생성 할 수 있습니다. @Override첫 번째의 예입니다. 리플렉션 API를 사용하여 슈퍼 클래스 중 하나에서 메서드 시그니처에 대한 일치 항목을 찾을 수 있는지 확인하고를 사용하여 Messager불가능한 경우 컴파일 오류를 발생시킵니다.

주석 처리기 작성에 대한 많은 자습서가 있습니다. 여기에 유용한 것이 있습니다. 컴파일러가 어노테이션 프로세서를 호출하는 방법에 대해서는 Processor인터페이스 의 메소드를 살펴보십시오 . 주요 작업은 process메서드에서 발생하며 컴파일러가 일치하는 주석이있는 요소를 볼 때마다 호출됩니다.


답변

다른 사람들이 제안한 것 외에도 주석이 어떻게 작동하는지 확인하기 위해 사용자 지정 주석과 프로세서를 처음부터 작성하는 것이 좋습니다.

예를 들어, 필자는 컴파일 타임에 메서드가 오버로드되었는지 확인하기 위해 주석을 작성했습니다.

먼저라는 주석을 만듭니다 Overload. 이 주석은 메서드에 적용되므로@Target(value=ElementType.METHOD)

package gearon.customAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(value=ElementType.METHOD)
public @interface Overload {

}

다음으로 정의 된 주석으로 주석이 달린 요소를 처리 할 해당 프로세서를 만듭니다. 로 주석이 달린 메소드 @Overload의 경우 서명이 두 번 이상 나타나야합니다. 또는 오류가 인쇄됩니다.

package gearon.customAnnotation;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

@SupportedAnnotationTypes("gearon.customAnnotation.Overload")

public class OverloadProcessor extends AbstractProcessor{

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // TODO Auto-generated method stub
        HashMap<String, Integer> map = new HashMap<String, Integer>();

        for(Element element : roundEnv.getElementsAnnotatedWith(Overload.class)){
            String signature = element.getSimpleName().toString();
            int count = map.containsKey(signature) ? map.get(signature) : 0;
            map.put(signature, ++count);
        }

        for(Entry<String, Integer> entry: map.entrySet()){
            if(entry.getValue() == 1){
                processingEnv.getMessager().printMessage(Kind.ERROR, "The method which signature is " + entry.getKey() +  " has not been overloaded");
            }
        }
        return true;
    }
}

주석 및 해당 프로세스를 jar 파일로 패키징 한 후 @Overloadjavac.exe를 사용 하여 클래스를 만들고 컴파일합니다.

import gearon.customAnnotation.Overload;

public class OverloadTest {
    @Overload
    public static void foo(){
    }

    @Overload
    public static void foo(String s){

    }

    @Overload
    public static void nonOverloadedMethod(){

    }
}

nonOverloadedMethod()실제로 오버로드되지 않았 으므로 다음과 같은 출력을 얻습니다.

여기에 이미지 설명 입력


답변

여기 @Override: http://www.docjar.com/html/api/java/lang/Override.java.html .

직접 작성할 수있는 주석과 구별되는 특별한 점은 없습니다. 흥미로운 부분은 주석 의 소비자 입니다. 와 같은 주석의 @Override경우 Java 컴파일러 자체, 정적 코드 분석 도구 또는 IDE에 있습니다.


답변

기본적으로 주석은 컴파일러 나 응용 프로그램에서 읽는 마커 일뿐입니다. 보존 정책에 따라 컴파일 타임에만 사용할 수 있거나 리플렉션을 사용하여 런타임에 읽을 수 있습니다.

많은 프레임 워크는 런타임 보존을 사용합니다. 즉, 클래스, 메서드, 필드 등에 일부 주석이 있는지 여부를 반사적으로 확인하고 주석이 있는지 여부에 따라 작업을 수행합니다. 또한 주석의 구성원을 사용하여 추가 정보를 전달할 수 있습니다.


답변

링크를 따르십시오 . 이것은 귀하의 문제에 대한 가까운 답변을 제공 할 것입니다. 에서 주석에 초점을 맞춘 경우 주석은 JavaJava 5에서 도입되었으며 Spring에만 국한되지 않습니다. 일반적으로 주석을 사용하면 클래스, 메서드 또는 변수에 메타 데이터를 추가 할 수 있습니다. 주석은 컴파일러 (예 : @Override 주석) 또는 Spring과 같은 프레임 워크 (예 : @Component 주석)에서 해석 할 수 있습니다.

또한 더 많은 참조를 추가하고 있습니다.

  1. http://www.codeproject.com/Articles/272736/Understanding-Annotations-in-Java
  2. http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/package-summary.html
  3. http://www.coderanch.com/how-to/java/AnnotationsExample


답변

나도 같은 질문에 대한 답을 찾고있었습니다. 아래 링크는 주석 내부를 가져 오기 위해 통합 된 좋은 기능을 제공했습니다. https://dzone.com/articles/how-annotations-work-java
도움이되기를 바랍니다 !


답변