애너테이션

이정연·2023년 1월 6일

자바기초

목록 보기
1/25

에너테이션

주석을 통해 코드에 대한 정보를 전달하기 위한 목적으로 만들어진 문법요소임
에너테이션은 다른 프로그램에게 정보를 전달한다.
소스코드가 컴파일되거나 실행될 때 컴파일러 및 다른 프로그램에게 필요한 정보를 전달하는 문법요소

public interface ExampleInterface{
	void example();
}

와 같이 interface를 먼저 지정해준 다음. 새로운 클래스를 만들어준다.

public class ExampleClass implements ExampleInterface {
}

그다음에 alt+insert를 누른 후 Implement Methods 를 클릭하고 메서드를 추가하면, 다음과 같이 자동으로 클래스에 interface 메서드가 추가된다.

public class ExampleClass implements ExampleInterface {
    @Override
    public void example() {

    }
}

@Override 가 에너테이션임 클래스, 인터페이스, 필드, 메서드 등에 붙여서 사용할 수 있다.
example() 이 추상메서드를 구현하거나 상위클래스의 메서드를 오버라이딩 한 메서드라는 것을 컴파일러에게 알려주게 된다.

애너테이션의 종류

표준애너테이션

자바가 기본적으로 제공하는 에너테이션

1. @Override

  • 메서드 앞에만 붙일 수 있음
  • 선언한 메서드가 상위 클래스의 메서드를 오버라이딩하거나 추상메서드를 구현하는 메서드라는 것을 컴파일러에게 알려줌
  • 클래스별로 같은이름의 메서드를 사용할 경우가 생기는데, 이경우 애너테이션을 붙여주면 상속받은 클래스의 애너테이션을 사용한다고 컴파일러에게 알려줌

규칙

  • 컴파일러가 @Override를 발견하면 @Override가 붙은 메서드와 동일한 이름을 가진 메서드를 상위 클래스에서 찾음
  • 위의 예시에서는 example() 메서드를 ExampleInterface interface 에서 검색함.
  • 없다면 컴파일 에러 발생
class a {
    public void example() {
        System.out.println("example() of SuperClass");
    }
}

class SubClass extends a {

    public void exapmle() {
        System.out.println("example() of SubClass");
    }
}

위의 예를 보면 두가지 클래스가 이름이 같은 메서드를 쓰고있다. 여기서 SubClass의 example() 메서드에 애너테이션을 안붙여주면
두개의 example() 메서드가 생성되게된다.

2. @Deprecated

  • 기존에 사용하던기술이 사용하지 않게 되었을 때 다른코드와의 호환성문제로 삭제하기 곤란할경우
  • 남겨야 하지만 더이상 사용하는것을 권장하지 않을때 사용

규칙

  • @Deprecated 가붙은 대상이 새로운것으로 교체되었음
  • 따라서 기존의 것을 사용하지 않도록 유도함.
public class Main{
    public static void main(String[] args) {
        OldClass oldClass = new OldClass();
        System.out.println(oldClass.getOldField());
    }

    class OldClass{
        @Deprecated
        private int oldField;

        @Deprecated
        int getOldField(){
            return oldField;
        }
    }
}

@Deprecated 가 붙일있으므로 oldClass.getOldField() 를 이용할 수 없다.

3. @SuppressWarnings

  • 컴파일 경고 메세지가 나타나지 않도록 함.
  • 경우에 따라 경고가 발생할 것이 충분히 예상됨에도 묵인해야 할 때 주로 사용함.
@SuppressWarnings({"deprecation", "unused", "null"})

다음과 같이 여러 경고유형을 나열함으로 써 여러개의 경고를 한번에 묵인 할 수 있게됨.

  • Deprecated 메서드를 사용한 경우에 발생하는 경고를 억제
  • unused : 사용하지 않는 코드와 관련된 경고를 억제
  • null : null과 관련된 경고를 억제

4. @FunctionalInterface

  • 함수형 인터페이스를 선언할 때 컴파일러가 선언이 바르게선언되었는지 확인
  • 바르게 선언되지 않은경우 에러를 발생시킴
  • 참고로 함수형 인터페이스를 단 하나의 추상메서드를 가지는 제약이있다.
@FunctionalInterface
public interface ExampleInterface {
	public abstract void example(); // 단 하나의 추상 메서드
}

다음과 같이 example(); 단 하나의 추상 메서드만 가져야 함.


메타 애너테이션

애너테이션을 정의하는 데에 사용되는 에너테이션
적용대상, 유지 기간을 지정하는데에 이용됨.
즉 애너테이션의 특성을 지정하는데에 사용되는 애너테이션

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{
}

위와 같이 @Override 애너테이션을 지정함에 있어서 다른 2가지 애너테이션(@Target, @Retention)이 이용됨을 알 수 있다.

1. @Target

  • 애너테이션을 적용할 "대상"을 지정하는데 사용됨.
  • 대상타입 대해 좀 더 찾아보도록하자 ------------------------------------
  • @Target(ElementType.xxxxxxxx)와 같이 ElementType 와 같이 쓴다. 뒤에 붙는것에는 FIELD, METHOD, TYPE 등이 있다.
import static java.lang.annotation.ElementType.*; 
//import문을 이용하여 ElementType.TYPE 대신 TYPE과 같이 간단히 작성할 수 있습니다.

@Target({FIELD, TYPE, TYPE_USE})	// 적용대상이 FIELD, TYPE 
public @interface CustomAnnotation { }	// CustomAnnotation을 정의


===================================================================

@CustomAnnotation	// 적용대상이 TYPE인 경우
class Main {
    
		@CustomAnnotation	// 적용대상이 FIELD인 경우
    int i;
}

CustomAnnotation 애너테이션에 대해서 @Target 으로 미리 적용대상을 설정해주고 Mail class 에 적용시키는 것을 볼 수 있다.
추가로, 애너테이션을 정의할 때 다음과같이 정의하면,

@Target({FIELD, TYPE, TYPE_USE})
public @interface CustomAnnotation { 
 String value();
 
 String comment() default "";
}
  • @CustomAnnotation을 사용할때
  • @CustomAnnotation(value = "값", comment = "값") 의형식으로 입력받을 수 있게됨. 즉, 메소드명이 애너테이션 괄호안에 넣을 변수명이 됨.
  • value()의 경우 입력시 생략가능함. 또한 String comment() default ""; 에서 defalut 값을 ""로 지정해줬기때문에 입력을 따로 안해도됨
  • @CustomAnnotation("값") 으로만 입력해도 된다!.

2. @Documented

  • 애너테이션에 대한 정보다 javadoc으로 작성한 문서에 포함되도록 하는 설정 --------------------------------------?
  • 표준 애너테이션과 메타애너테이션 중 @Override, @SuppressWarnings 를 제외하고 모두 적용되어있음.

3. @Inherited

  • 하위클래스가 애너테이션을 상속받도록 해줌
  • 이 애너테이션을 상위클래스에 붙이면 하위 클래스도 상위클래스에 붙은 애너테이션을 공유한다.
@Inherited
@interface SuperAnnotation{ }

@SuperAnnotation
class Super { }

class Sub extends Super{ } 

Super 클래스를 상속받은 Sub 클래스는 동일하게 @SuperAnnotation 에 정의된 내용들을 적용받게 됨.

4. @Retention

  • 애너테이션의 지속 시간을 결정하는데 사용됨.
  • 유지정책은 다음의 세가지가 있음.
  • SOURCE : 소스파일에 존재, 클래스 파일에는 존재하지않음. 컴파일시 사라짐
  • CLASS : 클래스파일에 존재, 컴파일까지만 유지
  • RUNTIME : 클래스파일에 존재, 자바가 VM에서 실행되는 동안에도 유지
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) 

소스파일에서 컴파일을 통해 바이트 코드로 되고, 로드가되면서 런타임으로 넘어간다.

SOURCE
  • Getter/Setter 같은 경우 롬복이 바이트 코드를 생성해서 넣어준다. 따라서 소스파일에만 존재해도될것임!
RUNTIME
  • 런타임에서 어노테이션 정보를 뽑아써야 할 때 이용 스프링의 경우 @Controller, @Service, @Autowired를 쓰게 되는데 이때 컴포넌트 스캔이 가능해야하기 때문에 RUNTIME중에도 에너테이션을 이용할 수 있어야함
CLASS
  • Maven/Gradle로 다운받은 라이브러리 같은 경우에 jar파일에는 소스가 포함되어있지 않다. .class파일만 존재한다. 따라서 파일만존재하는 라이브러리 같은경우에도 타입체커, IDE부가기능을 사용할수 있을라면 정책이 필요하다.
profile
반갑습니다.

0개의 댓글