아무도 주석이 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 파일로 패키징 한 후 @Overload
javac.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에 있습니다.
답변
기본적으로 주석은 컴파일러 나 응용 프로그램에서 읽는 마커 일뿐입니다. 보존 정책에 따라 컴파일 타임에만 사용할 수 있거나 리플렉션을 사용하여 런타임에 읽을 수 있습니다.
많은 프레임 워크는 런타임 보존을 사용합니다. 즉, 클래스, 메서드, 필드 등에 일부 주석이 있는지 여부를 반사적으로 확인하고 주석이 있는지 여부에 따라 작업을 수행합니다. 또한 주석의 구성원을 사용하여 추가 정보를 전달할 수 있습니다.
답변
이 링크를 따르십시오 . 이것은 귀하의 문제에 대한 가까운 답변을 제공 할 것입니다. 에서 주석에 초점을 맞춘 경우 주석은 Java
Java 5에서 도입되었으며 Spring에만 국한되지 않습니다. 일반적으로 주석을 사용하면 클래스, 메서드 또는 변수에 메타 데이터를 추가 할 수 있습니다. 주석은 컴파일러 (예 : @Override 주석) 또는 Spring과 같은 프레임 워크 (예 : @Component 주석)에서 해석 할 수 있습니다.
또한 더 많은 참조를 추가하고 있습니다.
답변
나도 같은 질문에 대한 답을 찾고있었습니다. 아래 링크는 주석 내부를 가져 오기 위해 통합 된 좋은 기능을 제공했습니다. https://dzone.com/articles/how-annotations-work-java
도움이되기를 바랍니다 !