애너테이션(Annotation)

김수민·2023년 3월 12일
0

백엔드 부트캠프

목록 보기
21/52

애너테이션

  • 애너테이션: 소스 코드가 컴파일되거나 실행될 때에 컴파일러 및 다른 프로그램에게 필요한 정보를 전달해주는 문법 요소
  • @Override가 바로 애너테이션. 애너테이션은 @로 시작하며, 클래스, 인터페이스, 필드, 메서드 등에 붙여서 사용할 수 있음
  • @Overrideexample()이 추상 메서드를 구현하거나, 상위 클래스의 메서드를 오버라이딩한 메서드라는 것을 컴파일러에게 알려주는 역할
  • 컴파일러 또는 다른 프로그램에게 필요한 정보를 제공

애너테이션의 종류

  • 표준 애너테이션: JDK에 내장되어 있는 일반적인 애너테이션
  • 메타 애너테이션: 다른 애너테이션을 정의할 때 사용하는 애너테이션
  • 사용자 정의 애너테이션: 사용자가 직접 정의해서 사용하는 애너테이션

표준 애너테이션

@Override

  • @Override는 메서드 앞에만 붙일 수 있는 애너테이션으로, 선언한 메서드가 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드라는 것을 컴파일러에게 알려주는 역할을 수행
class SuperClass {
    public void example() {
        System.out.println("example() of SuperClass");
    }
}

class SubClass extends SuperClass {

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

SuperClass의 example()를 SubClass에서 오버라이딩할 때, @Override를 붙여주면 컴파일러는 SubClass의 example()이 상위 클래스의 메서드를 오버라이딩한 것으로 간주됨.

  • 컴파일 과정에서 컴파일러가 @Override를 발견하면 @Override가 붙은 메서드와 동일한 이름을 가진 메서드가 상위 클래스(또는 인터페이스)에 존재하는지 검사함.
  • 만약 상위클래스(또는 인터페이스)에서 @Override가 붙어있는 메서드명과 동일한 이름의 메서드를 찾을 수 없다면 컴파일러가 컴파일 에러를 발생시킴

상위 클래스에 오버라이딩 메서드와 동일한 이름의 메서드가 존재하는지 확인해야하는 이유

  • 어던 메서드를 오버라이딩하거나 구현할 때, 개발자의 실수로 메서드의 이름이 잘못 작성되는 경우가 발생
  • 이러한 경우, @Override를 붙이지 않으면 컴파일러는 example()이라는 새로운 메서드를 정의하는 것으로 간주하고 에러를 발생시키지 않음
    -> 컴파일 에러 없이 코드가 그대로 실행될 수 있어 실행 시에 런타임 에러가 발생할 것이며, 런타임 에러 발생 시에 어디에서 에러가 발생했는지 에러의 원인을 찾아내기 어려워짐
  • @Override를 사용하면 example()이 오버라이딩 메서드라는 것을 컴파일러가 인지하고 상위클래스에 example()이 존재하는지 확인하기 때문에 이러한 상황을 방지할 수 있음

@Deprecated

  • @Deprecated: 기존에 사용하던 기술이 다른 기술로 대체되어 기존 기술을 적용한 코드를 더 이상 사용하지 않도록 유도하는 경우에 사용
  • 기존의 코드를 다른 코드와의 호환성 문제로 삭제하기 곤란해 남겨두어야만 하지만 더 이상 사용하는 것을 권장하지 않을 때 사용

@SupporessWarnings

  • 컴파일 경고 메시지가 나타나지않도록 함.
애너테이션설명
@SupressWarnings("all")모든 경고를 억제
@SupressWarnings("deprecation")Deprecated 메서드를 사용한 경우에 발생하는 경고를 억제
@SupressWarnings("fallthrough")switch문에서 break 구문이 없을 때 발생하는 경고를 억제
@SupressWarnings("finally")finally와 관련된 경고를 억제
@SupressWarnings("null")null과 관련된 경고를 억제
@SupressWarnings("unchecked")검증되지 않은 연사자와 관련된 경고를 억제
@SupressWarnings("unused")사용하지 않는 코드와 관련된 경고를 억제

중괄호에 여러 개의 경고 유형을 나열함으로써 여러 개의 경로를 한꺼번에 묵인하게 할 수 있음

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

@FunctionallInterface

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

메타 애너테이션

  • 메타 애너테이션(meta-annotation): 애너테이션을 정의하는데 사용되는 애너테이션, 애너티에션의 적용 대상 및 유지 기간을 지정하는 데에 사용됨.

@Target

  • 애너테이션을 적용할 "대상"을 지정하는 데 사용
대상 타입적용범위
ANNOTATION_TYPE애너테이션
CONSTRUCTOR생성자
FIELD필드(멤머변수, 열거형 상수)
LOCAL_VARIABLE지역변수
METHOD메서드
PACKAGE패키지
PARAMETER매개변수
TYPE타입(클래스, 인터페이스, 열거형)
TYPE_PARAMETER타입 매개변수
TYPE_USE타입이 사용되는 모든 대상
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;
}

@Documented

  • 애너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 하는 애너테이션 설정
  • 자바에서 제공하는 표준 애너테이션과 메타 애너테이션 중 @Override@SupressWarnings를 제외하고는 모두 @Documented가 적용되어 있음
@Documneted
@Target(ElementType.Type)
public @interface CustomAnnotation { }

@Inherited

  • 하위 클래스가 애너테이션을 상속받도록 함.
  • @Inherited 애너테이션을 상위 클래스에 붙이면 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용됨
@Inherited // @SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }

@SuperAnnotation
class Super { }

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

Super 상위 클래스로부터 확장된 Sub 하위 클래스는 상위 클래스와 동일하게 @SuperAnnotation에 정의된 내용들을 적용받게 됨

@Retention

  • 애너테이션의 지속 시간을 결저하는데 사용
유지정책설명
SOURCE소스파일에 존재, 클래스 파일에는 존재하지 않음
CLASS클래스 파일에 존재, 실행시에 사용불가, 기본값
RUNTIME클래스 파일에 존재, 실행시에 사용가능
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) 
//오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도 
//클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐
public @interface Override(){ }

Override 애너테이션은 컴파일러가 사용하면 끝나기 때문에 실행 시에는 더이상 사용되지 않음을 의미

@Repeatable

  • 애너테이션을 여러 번 붙일 수 있도록 허용한다는 의미
@interface Works {  // 여러개의 Work애너테이션을 담을 컨테이너 애너테이션 Works
    Work[] value(); 
}

@Repeatable(Works.class) // 컨테이너 애너테이션 지정 
@interface Work {
	String value();
}

@Repeatable 애너테이션은 일반적인 애너테이션과 달리 같은 이름의 애너테이션이 여러번 적용될 수 있기 때문에, 이 애너테이션을 하나로 묶어주는 애너테이션도 별도로 작성해야함.

사용자 정의 애너테이션

  • 사용자가 직접 애너테이션을 정의해서 사용하는 것
@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다. 
	타입 요소명(); // 애너테이션 요소를 선언
}

애너테이션은 java.lang.annotation 인터페이스를 상속받기 때문에 다른 클래스나 인터페이스를 상속받 수 없음

0개의 댓글