어노테이션( Annotation : 주석 )
- 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공한다.
- 실행시(런타임시) 특정 기능을 실행하도록 정보를 제공한다.
package east;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@Retention( RetentionPolicy.RUNTIME )
@interface Annot{} // Annotation 선언 방법.
@Annot
class Temp{
@Annot
public void print() {}
}
public class Main{
public static void main( String[] args ) throws Exception {
Class<?> cls = Class.forName("east.Temp");
Annotation at = cls.getAnnotation(Annot.class);
System.out.println( at ); // 실행 결과 : @east.Annot()
Method mtd = cls.getMethod("print");
Annotation at2 = mtd.getAnnotation( Annot.class );
System.out.println( at2 ); // 실행 결과 : @east.Annot()
}
}
- @interface Annot{} : Annot 이라는 이름의 어노테이션( 어노테이션은 인터페이스이다. )을 선언하는 코드이다.
- @Annot : 클래스 또는 멤버변수 위에 지정한다.
- cls.getAnnotation( Annot.class ) : 클래스에 Annot 이라는 이름의 어노테이션이 지정되었는지를 파악한다. 지정이 되어있다면 Annot의 인스턴스에 대한 포인터를 리턴한다. 안되어있다면 null 을 리턴한다. 마찬가지로 메서드에 어노테이션이 지정되어있는지를 확인할 때는 Method 에 getAnnotation 사용한다.>> mtd.getAnnotation( Annot.class );
[ CASE ]
예시 : @NoPrint 가 지정된 함수는 함수를 수행하기는 하지만 결과는 출력하게 하지 말아라
package east;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@Retention( RetentionPolicy.RUNTIME )
@interface NoPrint{}
class Calc{
@NoPrint
public int add( int i , int j ) { return i + j ; }
public int minus( int i , int j ) { return i - j ; }
}
public class Main{
public static void main( String[] args ) throws Exception {
Object obj = new Calc();
Class<?> cls = obj.getClass();
Method mtd = cls.getMethod( "add" , int.class , int.class );
Annotation at = mtd.getAnnotation( NoPrint.class );
int r = (int) mtd.invoke( obj , 20 , 10 );
if( at == null ) {
System.out.println( r );
}
}
}
- if( at == null ) { System.out.println( r ); } : NoPrint가 지정된 함수는 출력되지 않아야 하므로 getAnnotation 하여 NoPrint 가 null 인지 null이 아닌지 확인한다. null 일 경우 NoPrint 가 지정되지 않았다는 뜻이므로 결과값이 출력된다.
- 위의 코드의 경우 add 함수에는 NoPrint 주석이 있으므로 출력되지 않게 된다. 만약 add 함수에 NoPrint 주석을 삭제한다면 결과는 정상적으로 출력될 것이다.
- Annotation at = mtd.getAnnotation( NoPrint.class ); : 이런 식으로 메서드에 주석이 있는지 확인하여 어노테이션의 유무에 따라 특정 결과가 수행되도록 코드를 짜는것이 어노테이션의 핵심이다.
- 즉 어노테이션은 " 이 속성을 어떤 용도로 사용할까, 이 클래스에 어떤 역할을 줄까? " 를 결정해서 붙여준다고 할 수 있다.
[ CASE ] : 어노테이션에 key=value 값 지정하기.
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@interface NoPrint{
public int value() default 0;
public int abcd() default 0 ;
}
class Calc{
// value() 함수를 통해서 리턴받을 값을 여기서 지정가능하다.
@NoPrint( 30 )
public int add( int i , int j ){ return i + j;}
public int Minus( int i , int j ){ return i - j;}
}
public class Main{
public static void main( String[] args ) throws Exception {
String l = "add" ;
Object obj = new Calc();
Class<?> cls = obj.getClass();
Method mtd = cls.getMethod( l , int.class, int.class);
int r = (Integer)mtd.invoke( obj , 20 , 10 );
NoPrint at = (NoPrint)mtd.getAnnotation( NoPrint.class );
System.out.println( at.abcd() );
if( at == null ){
System.out.println( r );
}
else if( at.value() == r ){
System.out.println( r );
}
}
}
- @NoPrint( 30 ) : 이런 식으로 아무 키값 없이 값을 지정하려면 value() 함수를 이용해야 한다.
- @NoPrint( abcd = 30 ) : 특정 키( abcd )를 지정해 value 값을 지정하려면 value() 대신 abcd() 함수를 따로 선언해야 한다.
- @NoPrint( value = 20 , abcd = 30 ) >> 이런 식으로 2개 이상의 값을 한번에 지정할 수도 있다.
'JAVA > 정리한 것' 카테고리의 다른 글
| [ JAVA ] 소켓 통신 (0) | 2022.05.21 |
|---|---|
| [ JAVA ] 예외(Exception) 처리 (0) | 2022.05.20 |
| [ JAVA ] class.forName() (0) | 2022.05.18 |
| [ JAVA ] 정적( Static ) (0) | 2022.05.16 |
| [ JAVA ] 익명 클래스 ( Anonymous Class ) (0) | 2022.05.16 |