[SEB BE] Section 1. 애너테이션(Annotation)

박두팔이·2023년 1월 6일
0

자바

목록 보기
16/26

학습 목표

  • 애너테이션의 개념을 설명할 수 있다.
  • 표준 애너테이션을 이해하고 사용할 수 있다.
  • 메타 애너테이션이 무엇이고, 왜 필요한지 이해한다.
  • 사용자 정의 애너테이션을 정의하는 기초적인 문법을 이해한다.

애너테이션이란?

애너테이션은 소스 코드가 컴파일되거나 실행될 때에 컴퓨터에게 필요한 정보를 전달해주는 문법 요소이다.

  • @로 시작하며 클래스, 인터페이스, 필드, 메서드 등에 붙여서 사용할 수 있다.
public class ExampleClass implements ExampleInterface {
    @Override
    public void example() {

    }
}

여기에서 보이는 @Override가 바로 애너테이션이다.

애너테이션의 종류

  1. 표준 애너테이션 : 일반적인 애너테이션이다. JDK에 내장되어 있다.
  2. 메타 애너테이션 : 다른 애너테이션을 정의할 때 사용한다.

표준 애너테이션

  • @Override
  • @Deprecated
  • @SuppressWarnings
  • @FunctionalInterface

@Override

@Override는 컴파일러에게 “컴파일러야, 이 메서드는 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드인데, 만약에 내가 실수해서 오버라이딩 및 구현이 잘 안되면 에러를 발생시켜서 나에게 알려줄래?”라고 부탁하는것.

  • 메서드 앞에만 붙일 수 있다.
  • 상위클래스의 메서드를 오버라이딩(덮어쓰기)하거나 추상메서드를 구현하는 메서드일때 컴파일러에게 알려주는 역할이다.
class SuperClass {
    public void example() {
        System.out.println("example() of SuperClass");
    }
}

class SubClass extends SuperClass {

    @Override // 부모클래스의 example()메소드를 자식클래스가 오버라이드함
    public void example() {
        System.out.println("example() of SubClass");
    }
}

@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를 사용한다.

@SuppressWarnings

"경고가 발생할 것을 예상하지만 컴파일 경고메세지를 묵인해주세요"

@SuppressWarnings({"deprecation", "unused", "null"})

@FunctionalInterface (함수형 인터페이스를 선언)

"함수형 인터페이스의 선언이 바르게 선언되었나요?"

  • 함수형 인터페이스를 선언할 때 사용된다.
  • 함수형 인터페이스란 단 하나의 추상 메서드만 가져야 한다.
  • 함수형 인터페이스가 제대로 작성되었는지 컴파일러에게 검사해달라고 요구하는 애너테이션이다.
@FunctionalInterface
public interface ExampleInterface {
	public abstract void example(); // 단 하나의 추상 메서드
}

메타 애너테이션

  • 애너테이션을 정의하는 데에 사용되는 애너테이션이다.
  • 애너테이션의 적용대상과 유지기간을 정할 때 사용한다.

@Override(표준 애너테이션의 한 종류)의 소스코드를 보자

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

@Target(ElementType.METHOD) ,@Retention(RetentionPolicy.SOURCE) 이 두개의 애너테이션은 @Override 애너테이션을 사용할 때 사용된 애너테이션이다.

이 두가지는 @Override의 적용대상과 유지기간을 지정하는 역할을 하는 애너테이션이다.

또한, 애너테이션을 정의할 때는 @interface키워드를 사용하여 정의한다.
즉 Override가 애너테이션으로 사용되기 위해선 앞에 @interface를 붙여주어야 한다.

@Target : 대상을 지정할 때 사용됨

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;
}

애너테이션을 사용자가 직접 정의할 때(@interface 사용), @Target 애너테이션을 통해 사용자가 정의한 애너테이션이 어디에 적용될 수 있는지를 설정

@Documented : 애너테이션정보를 javadoc으로 작성한 문서에 포함하라는 애너테이션 설정

표준 애너테이션의 Override와 SuppressWarnings를 제외하고는 모두 @Documented애너테이션이 포함되있음.

@Inherited : "하위클래스는 애너테이션을 상속받아라!"

@Inherited애너테이션을 상위클래스에 붙이면 하위클래스도 상위클래스에 붙은 애너테이션들이 동일하게 적용된다. 아래의 코드를 살펴보면 상위클래스를 상속받은 하위클래스는 상위클래스와 동일하게 superAnnotation에 정의된 내용을 적용받게 된다.

@Inherited // @SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }

@SuperAnnotation
class Super { }

@SuperAnnotation //생략
class Sub extends Super{ } // Sub에 애너테이션이 붙은 것으로 인식

@Retention : "애너테이션의 지속시간을 결정해라"

애너테이션이 유지되는 기간을 정하는 속성(=유지정책)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) 
//오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도 
//클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐
public @interface Override(){ }

@Repeatable : "애너테이션을 여러번 붙일 수 있도록 허용합니다"

@Repeatable(Works.class) // Work 애너테이션을 여러 번 반복해서 쓸 수 있게 한다.  
@interface Work{  
    String value();  
}

work애너테이션을 하나의 대상에 여러번 적용하는 것이 가능함

@Work("코드 업데이트")  
@Work("메서드 오버라이딩")  
class Main{  
	... 생략 ...
}

사용자 정의 애너테이션

  • 사용자 정의 애너테이션은 사용자가 직접 애너테이션을 정의해서 사용한다. (자주사용되지는 x)
@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다. 
	타입 요소명(); // 애너테이션 요소를 선언
}
  • 애너테이션은 java.lang.annotation 인터페이스를 상속받는다.
  • 따라서 다른 클래스나 인터페이스를 상속받을 수 없다.
  • 'java custom annotation' 검색키워드를 이용하면 사용자정의 애너테이션의 자세한 내용을 확인할 수 있다.
profile
기억을 위한 기록 :>

0개의 댓글