JAVA/정리한 것

[ JAVA ] 어노테이션( Annotation )

따갓 2022. 5. 19. 00:14

어노테이션( 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