2011-03-25 7 views
9

자바에서 특수 효과 작업에 대한 몇 가지 질문이 있습니다.컴파일러가 주석을 처리하는 방법은 무엇입니까?

주석을 바이트 코드로 변환 할 수없는 경우이 정보는 어디로 이동합니까? 메타 데이터는 어디로 이동합니까? Java Reflection에서이 정보를 사용하는 방법은 무엇입니까?

컴파일러가 주석을 처리하는 방법은 무엇입니까? 자바 컴파일러는 무엇을

우리가 말할

을합니까

@Override 
public void doSomething(){ 
} 

?

메서드 서명을 검사하여 메서드가 완벽하게 재정의 된 메서드 여야한다는 것을 알고 있지만 어떻게해야합니까?

+0

이 정보가 http://pawanz.wordpress.com/2010/12/12/taming-java-annotations/ – ashishjmeshram

답변

9

주석의 세 가지 유형의 컴파일러가 추가 검사를 수행으로 http://download.oracle.com/javase/6/docs/api/java/lang/annotation/RetentionPolicy.html

@Override는 특수한 경우입니다 볼 수 있습니다.

+0

에 도움이되는지 확인해보십시오.'@ Override '주석이 컴파일러에서 처리되는 코드를 볼 수 있습니까? –

+0

@NikolayKuznetsov 예, OpenJDK에서'javac '소스를 읽음으로써 –

0

이것은 간단합니다. 컴파일러는 수퍼 클래스에서 동일한 이름과 동일한 수의 매개 변수, 순서 및 유형을 가진 메소드를 확인합니다. 메서드에 @Override 주석이 있고 그러한 메서드를 찾을 수없는 경우 오류가 생성됩니다.

더 흥미로운 질문은 컴파일러가 런타임에 의미가있는 주석을 처리하는 방법입니다. 나는 그들이 바이트 코드로 추가되었다고 가정하지만, 메타 정보가있는 특별한 섹션에있다. 그래서, 런타임에 jvm은 메타 섹션에 접근 할 수 있습니다. 증명 자료로 class 개체에서 항상 getAnnotations()으로 전화 할 수 있습니다. 그러므로 (따라서 논리적으로 컴파일 된 바이트 코드가 존재하지 않는) 런타임시에 사용할 수없는 - 특정 방식이 재정의있어서의 계약을 따르는 지 확인하기 위해 사용 -

4

@Override소스 형 주석이다.

나는 방법은 완벽하게 재정의 된 메서드해야 있도록 메서드 서명을 확인 알지만, 어떻게 소스 파일을 읽고 바이트 코드로 변환하는 과정에서

, 예를 들면,하지 전혀 반사를 사용합니다. 추가 컴파일러 정보는 The Java Programming Language Compiler - javac을 참조하십시오.

-2

컴파일 된 주석 (궁극적으로 상수 데이터 임)은 클래스 파일에 저장되며 getAnnotations() 및 friends 메소드를 사용하여 액세스 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. "상수 풀 (constant pool)"이 무엇인지, 런타임에 어떻게 사용되는지 자세히 설명해 주실 수 있습니까? – Gunwant

+0

이것은 상수 데이터가 저장되는 클래스 파일의 영역입니다. JVM 참조를 읽을 수도 있습니다. – Ingo

+0

유용한 정보를 제공해 주셔서 감사합니다. – Gunwant

3

주석은 public @interface @Override {}로서 구현 @Override 주석 클래스 파일에 저장 될 수있는 RetentionPolicy 갖는다 (RetentionPolicy.CLASSRetentionPolicy.RUNTIME)를 예컨대 또는 (RetentionPolicy.SOURCE) 폐기 될 수있다.

메서드의 RetentionPolicy는 RetentionPolicy.SOURCE이고 ElementType.METHOD이라는 대상 (이 메서드는 메서드 선언에만 주석을다는 의미)

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.SOURCE) 
public @interface Override { 
} 

PS 당신이 반사적으로 주석을 읽고 싶다면, 당신은 RetentionPolicy.RUNTIME에 RetentionPolicy을 설정해야합니다.

2

처음에는 두 가지 종류의 주석이있었습니다. 런타임에 액세스 할 수 있고 (2 종류) 런타임에 액세스 할 수 없습니다. 주석의 동작은 주석 선언의 주석을 통해 보존 정책에 의해 수행됩니다. 예 :

@Retention(RetentionPolicy.RUNTIME) // effectively visible to JVM Runtime 
public @interface MethodInfo { 
    String author() default "unspecified"; 
    String lastModification() default "unspecified"; // Format: yyyy-mm-dd 
    ImplementationStatus implementationStatus(); 
} 

JVM 런타임 표시 주석은 주석 코드 실행 (혹은 때 JVM이로드된다) 동안의 반사를 통해 액세스 될 수있다. 이러한 주석을 메타 데이터 소유자로 사용합니다. 메타 데이터는 다른 코드로 처리되어 다양한 작업을 수행 할 수 있습니다. 주어진 메소드가 실행되기 전에 주석 처리 된 메소드 구현 상태를 검사한다.

하지만 누군가는 반사를 통해 주석 matedata를 사용하는 코드를 작성해야합니다! 가장 좋은 예는 배치 된 JAR 파일로부터 요청시 클래스를로드하는 응용 프로그램 서버 (AS)입니다. 이는 특정 디렉토리입니다. AS는 @Initialization 주석으로 주석 처리 된 정적 메소드에 대해로드 된 각 클래스를 검사하는 코드를 포함 할 수 있으며 해당 메소드를 즉시 실행합니다. 이 주석 유형은 AS에 의해 정의되며 AS 용 JAR 및 클래스를 작성하는 사용자는 개발 중에이를 사용합니다.

런타임 중에 사용할 수없는 주석은 컴파일 중에 사용되며 해결됩니다. @Override가 좋은 예입니다. 사용자 정의 소스 전용 주석은 컴파일러 플러그인에서 사용하거나 필요에 따라 코드가 다른 코드에 의해 컴파일되는 경우 사용할 수 있습니다.

관련 문제