Anotation
- Java Annotation?
: 어노테이션은 어노테이션된 요소들의 행동으로부터 프로그램의 행위를 추출하여, 필요하다면 컴파일러나 VM이 상호 의존적인 코드를 생성하는, 프로그램 요소와 메타 태그에 관계된 매커니즘.
: 사전적으로는 "주석"이라는 의미를 가지고 있으며, 의미대로 자바 코드에 주석처럼 달아 특수한 의미를 부여해준다. 이 특별한 의미는 컴파일 타임 또는 런타임에 해석 될 수 있다.
- .java부터 .class까지
: .java => Parser => Type checker => [Annotation Checker] => Class File writer => .class
- 어노테이션 규칙
: @interface + 어노테이션 이름
: 어노테이션 소스코드 내부의 메소드 선언은 매개변수를 지닐 수 없다.
: 어노테이션 소스코드 내부의 메소드 선언은 clauses를 throw 할 수 없다.
: 메소드의 반환 타입은 primitives, String, Class, enum과 primitives배열, String배열, Class배열, enum배열 중 하나이다.
- 분류
1. marker ; @AnnotationTypeName
: 멤버 변수가 없으며, 단순히 표식으로서 사용되는 어노테이션이다. 컴파일러에게 어떤 의미를 전달한다.
2. single-element ; @AnnotationTypeName(single-element)
: 멤버로 단일변수만을 갖는 어노테이션이다. 단일변수 밖에 없기 때문에 (값)만을 명시하여 데이터를 전달할 수 있다.
3. normal, full-value, multi-value ; @AnnotationName(element=value, element=value, ...)
: 멤버로 둘 이상의 변수를 갖는 어노테이션으로, 데이터를 (값=쌍)의 형태로 전달한다.
- Built-in Annotation
== java.lang.annotation (meta-annotation)
@Retention
: Retention은 어노테이션이 얼마나 오랫동안 유지되는지에 대해, JVM이 어떻게 사용자 어노테이션을 다루어야 하는지를 서술합니다.
* SOURCE - 어노테이션이 컴파일 타임시 버려진다는 것을 의미합니다. retention정책이 source로 정의되어 있으면, 클래스 파일은 어노테이션을 지니지 못합니다.
* CLASS - 어노테이션이 생성된 클래스 파일에서 나타날 것이라는 것을 의미합니다. 그러나 런타임시에는 이 어노테이션을 이용하지 못합니다.
* RUNTIME- 이는 런타임시 JVM에서 어노테이션의 이용이 가능하다는 것을 의미합니다. 이러한 어노테이션을 읽는 사용자 로직을 가짐으로써 런타임시 무언가를 할 수 있습니다.
@Target
: Target은 어디에 어노테이션을 넣을 수 있는지를 서술합니다. field, method, class가 정의된 곳에 어노테이션을 넣을 수 있습니다.
* TYPE - class, interface, enumeration에 어노테이션을 적용할 수 있다는 것을 의미합니다.
* METHOD - method 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* PARAMETER - parameter 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* PACKAGE - package 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* FIELD - field 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* LOCAL_VARIABLE - 지역 변수 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* CONSTRUCTOR - 생성자에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
* ANNOTATION_TYPE - 어노테이션 타입에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
@Inherited
- 기본적으로 어노테이션은 상속되지 않습니다. 따라서 상속을 원한다면, 어노테이션을 Inherited 해야 합니다. Inherited 어노테이션이 사용자 어노테이션에 놓여야 하며, 이는 클래스에만 효과가 있습니다. (즉, 상속받는 클래스도 같은 어노테이션 사용)
@Documented
- 어노테이션이 기본으로 javadoc 및 유사한 툴에 의해 문서화 되는 것을 나타냅니다. 이러한 형태는 타입의 선언에 주석을 달기 위해 사용합니다. 어노테이션은 클라이언트에 의해 어노테이션된 요소의 사용에 영향을 미치게 됩니다. 타입의 선언에 Documented 어노테이션을 붙인 경우, 그 어노테이션은 어노테이션된 요소의 공개 API중 한 부분이 됩니다.
@Override
: 현재 메소드가 수퍼클래스의 메소드를 오버라이드한 메소드임을 컴파일러에게 명시한다. 만일 수퍼 클래스에 해당하는 메소드가 없으면 컴파일러가 인지하고 에러를 발생시켜 준다.
@Deprecated
: 마커 오노테이션으로 차후 버전에 지원되지 않을 수 있기 때문에 더 이상 사용되지 말아야할 메소드를 나타낸다. 특이하게 더이상 사용되지 말아야할 메소드와 같은 라인상에 놓여져야 한다.
@SuppressWarnings
: 의미대로 경고를 제거하는 어노테이션이다. Object형을 엘리먼트로 하는 컬렉션을 사용하면, 컴파일러 경고가 발생하는데 이 어노테이션을 사용하여 프로그래머의 의도적인 Object형 사용임을 알려 경고를 제거할 수 있다.
출처: http://www-01.ibm.com/support/knowledgecenter/SSQ2R2_9.1.0/org.eclipse.jdt.doc.user/tasks/task-suppress_warnings.htm?lang=ko
Java 5.0부터 java.lang.SuppressWarning
어노테이션을 사용하여 컴파일 단위의 서브세트와 관련된 컴파일 경고를 사용하지 않도록 설정할 수 있습니다.
어노테이션이 없으면 컴파일러에서 로컬 변수 s
를 사용할 수 없습니다. 어노테이션을 사용하여 컴파일러는 이 경고를 foo
메소드에 대해 로컬에서 무시합니다. 이러한 경우 동일한 컴파일 단위 또는 동일한 프로젝트의 다른 위치에 경고를 보관할 수 있습니다.
SuppressWarnings
어노테이션 내부에서 사용할 수 있는 토큰 목록은 다음과 같습니다.
- all 모든 경고를 억제합니다.
- boxing boxing/unboxing 오퍼레이션과 관련된 경고를 억제합니다.
- cast 캐스트 오퍼레이션과 관련된 경고를 억제합니다.
- dep-ann 권장되지 않는 어노테이션과 관련된 경고를 억제합니다.
- deprecation 권장되지 않는 기능과 관련된 경고를 억제합니다.
- fallthrough switch 문에서 누락된 break 문과 관련된 경고를 억제합니다.
- finally 리턴되지 않는 마지막 블록과 관련된 경고를 억제합니다.
- hiding 변수를 숨기는 로컬과 관련된 경고를 억제합니다.
- incomplete-switch switch 문에서 누락된 항목과 관련된 경고를 억제합니다(enum case).
- javadoc javadoc 경고와 관련된 경고를 억제합니다.
- nls 비nls 문자열 리터럴과 관련된 경고를 억제합니다.
- null 널(null) 분석과 관련된 경고를 억제합니다.
- rawtypes 원시 유형 사용법과 관련된 경고를 억제합니다.
- resource 닫기 가능 유형의 자원 사용에 관련된 경고 억제
- restriction 올바르지 않거나 금지된 참조 사용법과 관련된 경고를 억제합니다.
- serial 직렬화 가능 클래스에 대한 누락된 serialVersionUID 필드와 관련된 경고를 억제합니다.
- static-access 잘못된 정적 액세스와 관련된 경고를 억제합니다.
- static-method static으로 선언될 수 있는 메소드와 관련된 경고를 억제합니다.
- super 수퍼 호출을 사용하지 않는 메소드 겹쳐쓰기와 관련된 경고를 억제합니다.
- synthetic-access 내부 클래스로부터의 최적화되지 않은 액세스와 관련된 경고를 억제합니다.
- sync-override 동기화된 메소드를 오버라이드하는 경우 누락된 동기화로 인한 경고 억제
- unchecked 미확인 오퍼레이션과 관련된 경고를 억제합니다.
- unqualified-field-access 규정되지 않은 필드 액세스와 관련된 경고를 억제합니다.
- unused 사용하지 않은 코드 및 불필요한 코드와 관련된 경고를 억제합니다.
참고: http://netpyoung.tistory.com/100, http://hiddenviewer.tistory.com/88, https://en.wikibooks.org/wiki/Java_Programming/Annotations/Meta-Annotations
- Custom Annotation
: 클래스와 같이 어노테이션을 임의로 정의하여 사용할 수 있다. 어노테이션은 interface 키워드 앞에 @를 붙여 표시한다.
: @interface InProgress{}
- 예제
package kr.co.ioacademy; // ioacademy 윤찬식 강사님 // Simple JUnit4 // 어노테이션(Annotation) ; 주석 // Comment : 비공식적이고 임시적이다. // 정의 : 자바의 각 요소(클래스, 메소드, 필드, 매개변수) 가 가질 수 있는 // 주석 리소스 // 목적 // 1. 컴파일러에게 추가적인 정보 전달 // 2. 컴파일 할 때와 설치시의 작업 지정 // 3. 실행할 때 별도의 처리를 수행 // 기본 어노테이션 // 1. @Override // 2. @Deprecated // 3. @SuppressWarnings // 1. 어노테이션을 만드는 방법. import java.lang.annotation.*; import java.lang.reflect.Method; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface Test { boolean enabled() default true; } public class Example7 { @Test public void testA() { System.out.println("testA : do something"); } @Test(enabled = true) public void testB() { System.out.println("testB : do something"); throw new RuntimeException("failed to run"); } @Test(enabled = true) public void testC() { System.out.println("testC : do something"); } public static void main(String[] args) { System.out.println("Testing...."); int count = 0; int passed = 0; int failed = 0; int ignore = 0; Class obj = Example7.class; for (Method method : obj.getDeclaredMethods()) { if (method.isAnnotationPresent(Test.class)) { ++count; Annotation annotation = method.getAnnotation(Test.class); Test test = (Test) annotation; if (test.enabled()) { try { method.invoke(obj.newInstance()); ++passed; System.out.printf("Test '%s' - passed\n", method.getName()); } catch (Throwable e) { ++failed; System.out.printf("Test '%s' - failed : %s\n", method.getName(), e.getCause()); } } else { ++ignore; System.out.printf("Test '%s' ignored\n", method.getName()); } } } // for System.out.printf("Result - Total:%d, Passed:%d, Failed:%d, Ignore:%d\n", count, passed, failed, ignore); } }
'Programing > Java' 카테고리의 다른 글
Effective Java - Exception (0) | 2016.03.09 |
---|---|
Effective Java - Reflection (0) | 2016.03.08 |
Effective Java - 스레드(2) (0) | 2016.03.07 |
Effective Java - 스레드(1) (0) | 2016.03.07 |
Effective Java - 불변 객체 (0) | 2016.03.07 |