Deperecated/JAVA

JAVA - 어노테이션

누알라리 2020. 1. 9. 14:46

머리털 나고 처음 보는 개념이라 잘 읽히지도 않고.. 그냥 쓰면서 공부해야 조금이라도 머리 속에 들어올듯.

 

1. 메타데이터(metadata)

- 응용 프로그램이 처리해야 할 데이터가 아니라, 컴파일&실행 과정에서 코드를 어떻게 컴파일하고 처리할 것 인지를 알려주는 정보.

- 그 코드 자신에 대한 설명을 담은 데이터라고 이해할 수 있다.

- 어노테이션을 메타데이터의 일종이라고 볼 수 있다.

 

2. 용도

- 컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공

- 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공

- 실행 시(런타임 시) 특정 기능을 실행하도록 정보를 제공

 

3. 용도의 예

- @Override 어노테이션의 경우 : 메소드가 오버라이드 된 것을 컴파일러에게 알려주어 컴파일러가 오버라이드 검사를 하게함.

- 빌드 시 자동으로 XML 설정 파일을 생성하기도 함.

- 배포를 위해 JAR 압축 파일을 생성

- 실행 시 클래스의 역할을 정의 하기도 한다.

 

-> 내 생각에 배포자나 툴 개발자가 라이브러리에 어노테이션을 선언하고, 자유롭게 쓸 수 있도록 제공하는식인듯(?)

 

4. 사용 방법

// 1. 어노테이션 정의.

@AnnotationName

// 2. 어노테이션은 element를 멤버로 가질 수 있으며,
//    타입으로는 int 등 기본 데이터 타입, String, 열거 타입, Class 타입, 이들의 배열 타입을
//    이용할 수 있다.

@AnnotationName(elementName="값", elementName2=3);

// 3. 어노테이션은 기본 엘리먼트인 value를 가질 수 있다.

@AnnotationName(3);
@AnnotationName("값");

// 4. 기본 엘리먼트 value와 다른 엘리먼트의 값을 동시에 줄 수도 있다.

@AnnotationName(value="값", elementName2="3);

 

5. 적용 대상

- 어노테이션을 적용 할 수 있는 대상은 java.lang.annotation.ElementType에 정의되어 있다.

- 클래스, 인터페이스, 열거 타입, 필드, 생성자, 메소드, 로컬 변수, 패키지 등에 적용할 수 있다.

- 적용 예)

// 클래스에 적용된 어노테이션
@ClassAnnotation
public class ClassName
{
	//필드에 적용된 어노테이션
	@FieldAnnotation
    String FieldName;
    
    //메소드에 적용된 어노테이션
    @MethodAnnotation
    bool IsMyName(); 
}

6. @Target

- 자신이 만든 어노테이션에 사용될 자바 요소를 지정할 수 있다.

// @Target의 기본 엘리멘트 value는 ElementType 배열을 값으로 가진다.
// 이는 어노테이션이 적용될 대상을 복수개로 지정하기 위함이다.

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@AnnotationName

// 이렇게 어노테이션을 적용할 경우,
// 클래스, 필드, 메소드에 어노테이션을 적용할 수 있다.

7. 유지 정책

- 사용 용도에 따라 어노테이션을 어느 범위까지 유지할 것인지 지정해야 한다.

- 소스상에서만, 컴파일된 클래스까지, 런타임 시에도 유지할것인지를 지정해야 한다.

- 이 정보는 java.lang.annotation.RetentionPolicy 열거 상수에 정의 되어 있다.

RetentionPolicy 설명
SOURCE

소스상에서만 어노테이션 정보 유지.

소스코드 분석 시에만 의미가 있으며,

바이트 코드 파일에는 정보가 남지 않는다.

CLASS

바이트 코드 파일까지 어노테이션 정보 유지.

리플렉션을 이용해서 정보를 얻을 수 없다.

RUNTIME

바이트 코드 파일까지 어노테이션 정보를 유지하면서

리플렉션을 이용해 런타임 시에 어노테이션 정보를 얻을 수 있다.

8. 리플렉션

- 런타임 시에 클래스의 메타 정보를 얻는 기능

- 클래스가 갖고 있는 필드, 생성자, 메소드, 어노테이션을 런타임 중에 알아내는 것.

- 우리가 작성하는 어노테이션은 대부분 런타임 시점에 사용하기 위한 용도로 만들어진다.

- 사용 예)

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@AnnotationName

 

- 어노테이션 자체는 아무런 동작을 가지지 않는 메타데이터이지만, 리플렉션을 이용해서 어노테이션의 적용 여부와 엘리먼트 값을 읽고 적절히 처리할 수 있다.

 

9. 어노테이션 적용 예)

 

// 1. 어노테이션 정의

package Hyunndy_Toy_Package;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(METHOD)
public @interface PrintAnnotation {
	String value() default "-";
	
	int lines() default 15;
}

 

// 2. 어노테이션 적용 클래스

package Hyunndy_Toy_Package;

public class Service {
	
	@PrintAnnotation
	public void Method1()
	{
		System.out.println("실행 내용1");
	}
	
	@PrintAnnotation("*")
	public void Method2()
	{
		System.out.println("실행 내용2");		
	}
	
	@PrintAnnotation(value="#", lines=20)
	public void Method3()
	{
		System.out.println("실행 내용3");
	}
	
}

// 3. Main()이 존재하는 Class에서 리플렉션을 이용해 어노테이션 정보를 읽고 엘리먼트 값, 메소드를 호출.

package Hyunndy_Toy_Package;
import java.lang.reflect.*;

public class Hyunndy
{
	public static void main(String[] args)
	{
		//Service 클래스로 부터 메소드 정보를 얻음.
		Method[] declaredMethods = Service.class.getDeclaredMethods(); //[리플렉션] Service 클래스에 선언 된 메소드 얻기
		
		for(Method method : declaredMethods)
		{
			//[리플렉션] PrintAnnotation 어노테이션이 적용되었는지 확인.
			if(method.isAnnotationPresent(PrintAnnotation.class))
			{
				//[리플렉션] 어노테이션 객체 얻어오기.
				PrintAnnotation p = method.getAnnotation(PrintAnnotation.class); 
				
				System.out.println("[" + method.getName() + "]"); 
				
				for(int i=0; i<p.lines(); i++)
				{
					System.out.print(p.value());
				}
			
				System.out.println();
				
				try
				{
					method.invoke(new Service());
				}
				catch(Exception e) {}
				      
				System.out.println();
			}
		}
	}
}

'Deperecated > JAVA' 카테고리의 다른 글

JAVA - 익명 구현 객체, 람다식  (0) 2020.01.09
JAVA - 인터페이스  (0) 2020.01.09
JAVA 기본서 공부 5 - 클래스  (0) 2020.01.05
JAVA - 열거 타입  (0) 2020.01.04
JAVA - 향상된 for문  (0) 2020.01.04