[F-lab 모각코 챌린지 24일차] TIL

JeongheeKim·2023년 6월 24일

TIL

목록 보기
24/66

자바는 클래스와 인터페이스의 메타정보(패키지 정보, 타입정보, 생성자, 필드 메소드 정보 등)를 클래스로 관리한다.

애노테이션이란

  • 프로그램에게 추가적인 정보를 제공해 주는 메타데이터
    • 어노테이션은 동작이 있는것이 아니라 단순 설정 정보일뿐이다. 리플랙션을 이용해서 적용대상으로 부터 어노테이션 정보를 얻을 수 있다.
  • 어노테이션은 클래스 또는 인터페이스를 컴파일 하거나 실행할 때 어떻게 처리해야하는지 알려주는 설정 정보

annotation 용도

  1. 컴파일 시 사용하는 정보 전달
    • ex) 메서드가 재정되가 제대로 되었는지 확인 @Override
  • 프로그램 실행 시 특정 기능을 처리할 때 사용하는 정보 전달

애노테이션 정의하는 방법

클래스나 메서드 위에 사용할 애노테이션을 붙이거나 직접 커스텀이 가능하다.

커스텀 애노테이션 작성 방법

  1. 애노테이션으로 지정할 이름과 동일하게 클래스를 생성한다. AnnotationName.java

애노테이션 정의 시 하나 이상의 엘리먼트 멤버 선언 가능 (어노테이션을 코드에 적용할 때 외부의 값을 입력받을 수 있도록 하는 역할)

public @interface AnnotationName{
	String elementName1();//요소
}
  1. 애노테이션을 클래스에 적용한다.
@AnnotationName(elmentName1="값");//선언시 @를 붙여서 컴파일러에게 어노테이션이라고 알려준다.

애노테이션 작성 시 여러 요소들이 있다면, 어노테이션 적용 시 요소들의 값을 빠짐없이 지정해주어야 한다.

3. 애노테이션을 이용하여 실행


표준 어노테이션

자바에서 기본으로 제공하는 어노테이션

@Overried, @Deprecated, @SuppressWarnings는 JDK 1.5에 등장 @FuntionalInterface는 JDK1.8에 등장했다.

@Override

  • 부모클래스에 있는 메서드를 오버 라이딩하는 것이라는 걸 컴파일러에게 알려준다.

@Deprecated

  • 더 이상 사용하지 않는 필드나 메서드에 사용

@SuppressWarnings

  • 컴파일러에게 프로그래머가 의도한 코딩이므로 컴파일러에게 무시하도록 할 경우 사용
  • 경고 메시지 종류
    • deprecation :@Deprecated가 붙은 대상을 사용할 경우
    • unchecked : 제네릭 타입을 지정하지 않았을 경우
    • varargs : 가변 인자의 타입이 제네릭 타입일 경우
    • rawtypes : 제네릭스를 사용하지 않아서 발생하는 경우
@SuppressWarnings({"rawtypes","unchecked"})

@FunctionalInterface

함수형 인터페이스 선언 시 어노테이션을 붙여서 함수형 인터페이스를 제대로 선언했는지 확인한다.


메타 애노테이션

애노테이션을 정의 시 어노테이션의 적용대상(target) 및 유지기간(retention)을 지정하는 데 사용하며, java.lang.annotation 패키지에 포함되었다.

@Retention

애노테이션이 유지되는 기간을 지정하는 데 사용

애노테이션 유지 정책

Retention Policy적용 시점제거 시점
SOURCE컴파일 시 적용컴파일 후 제거
CLASS메모리 로딩 시 적용메모리로 로딩 후 제거됨
RUNTIME런타임시 까지 어노테이션이 유효하며, 실행 시 리플렉션을 통해 클래스 파일에 저장된 어노테이션 정보를 읽어서 처리된다.실행시 어노테이션 정보가 가상머신에 의해서 참조 가능실행 이후에도 계속 유지됨

오버라이드 유지 정책은 SOURCE이므로 소스파일에서만 적용된다.

Annotation 유지정책 테스트

SOURCE, CLASS, RUNTIME 각각 유지정책을 가지는 어노테이션을 생성했다.

@Retention(RetentionPolicy.CLASS)
public @interface ClassRetention {
	String value() default "ClassRetention";
}

@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeRetention {
	String value() default "Runtime Retention";
}

@Retention(RetentionPolicy.SOURCE)
public @interface SourceRetention {
	String value() default "Source Retention";
}

각각의 어노테이션이 적용된 클래스의 어노테이션 정보를 가져왔다.

public class UserAnnotationSample {
	public static void main(String[] args) {
		Annotation a[] = new A().getClass().getAnnotations();
		Annotation b[] = new B().getClass().getAnnotations();
		Annotation c[] = new C().getClass().getAnnotations();

		System.out.println("a annotation length = " + a.length);
		System.out.println("b annotation length = " + b.length);
		System.out.println("c annotation length " + c.length);

		System.out.println("c[0] = " + c[0]);
	}

}
@SourceRetention
class A {
}

@ClassRetention
class B {
}

@RuntimeRetention
class C {
}

결과를 보면 RUNTIME 유지정책을 택한 어노테이션만이 runtime시 확인 할 수 있었다.

a.length = 0
b.length = 0
c.length = 1
c[0] = @RuntimeRetention(value="Runtime Retention")

@Target

애노테이션 적용대상 지정 시 사용

  • 코드상에서 어노테이션을 적용할 수 있는 대상 설정
  • java.lang.annotation.ElementType 열거 상수로 정의되어 있음
    • 이는 복수개로 적용대상을 지정하기 위해서임
  • 타깃으로 올 수 있는 타입
    • TYPE(클래스, 인터페이스, 열거 타입)
    • ANNOTATION_TYPE(어노테이션)
    • FIELD(필드)
    • CONSTRUCTOR(생성자)
    • METHOD(메서드)
    • LOCAL_VARIABLE(로컬 변수)
    • PACKAGE(패키지)

여러 개 타깃으로 지정할 때는 배열 형식으로 작성해야 한다.

@SuppressWarning에 표시된 @Target 어노테이션

@Documented

애노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.

@Override , @SuppressWarnings를 제외하고는 모두 @documented 어노테이션이 붙어있다.

Reflection

  • 이미 로딩이 된(=Runtime 시) 클래스에서 다른 class를 동적으로 로딩하여(Dynamic loading) 메타정보를 프로그램에서 읽고 수정하는 행위를 리플렉션이라한다.
  • JVM에서 실행되는 어플리케이션의 런타임 동작을 검사하거나 수정할 수 있는 기능
    • 예시) 스프링에서 런타임 시 개발자가 등록한 빈을 애플리케이션에서 가져와 사용할 수 있도록 처리
  • 어노테이션 설정 정보를 이용한 리플렉션 관련 메소드
    isAnnotationPresent지정한 어노테이션이 적용되었는지 여부를 전달
    getAnnotation지정한 어노테이션이 존재하면 리턴 아닐경우 null
    getDeclaredAnnotations적용된 어노테이션 리턴
  • 단점
    • 리플렉션을 사용하면 접근 제어자와 무관한게 접근 가능하다.
      • private 필드나 메소드에 대해 런타임 시 접근 가능하므로 외부 노출로 인한 캡슐화가 깨질 수 있다.

애노테이션 프로세서

컴파일 시 끼어들어 특정한 어노테이션이 있는 코드를 참조하여 소스코드를 만들어내는 기능

예시) lombok(어노테이션 설정으로만으로 반복적인 코드 생성을 도와주는 라이브러리)


[참고]

https://medium.com/msolo021015/자바-reflection이란-ee71caf7eec5

youtu.be/zNmq-qGzsUY

youtu.be/GQYoIl9 sOlk

자바의 정석 - 어노테이션

www.inflearn.com/course/the-java-code-manipulation#curriculum

https://www.geeksforgeeks.org/java-retention-annotations/

https://madplay.github.io/post/java-reflection

https://docs.oracle.com/javase/tutorial/reflect/index.html

https://hudi.blog/java-reflection/

0개의 댓글