[JAVA] 애노테이션

2024. 9. 2. 19:21·Back-End/Java

[작성일: 2023. 02. 08]

 

 

애너테이션

  • 주석처럼 프로그래밍 언어에 영향을 미치지 않으며 유용한 정보(설정 정보 등)를 제공하는 것.
@Test  // 이 메서드가 테스트 대상임을 테스트 프로그램에게 알림 (JUnit)
public void method() {
  ...
}

 

 

 

 

 

표준 애너테이션

@Override
- 컴파일러에게 오버라이딩하는 메서드라는 것을 알림.
- 오버라이딩을 올바르게 했는지 컴파일러가 체크하게 함.
- 오버라이딩 할 때 메서드 이름을 잘못 적는 실수 하는 경우가 많으니 사용해 볼 것.
class Parent {
  void parentMethod() {}
}

class Child extends Prent {
  @Override
  boid parentMethod() {} 
}



@Deprecated
- 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙임. (취소선 나타남)
- @Deprecated의 사용 예 : Date 클래스의 getDate()
- @Deprecated를 붙인 코드를 컴파일하면 경고메시지가 나옴.

@Deprecated
public int getDate() {
  return normalize().getDayOfMonth();
}



@SuppressWarnings
- 컴파일러의 경고메세지가 나타나지 않게 억제함.
- 괄호() 안에 억제하고자 하는 경고의 종류를 문자열로 지정함.
- 둘 이상의 경고를 동시에 억제 가능.
- '-Xlint' 옵션으로 컴파일하면 경고메시지를 확인할 수 있음.

@SuppressWarnings("unchecked")  // 지네릭스와 관련된 경고를 억제
ArrayList list = new ArrayList();  // 지네릭 타입 지정하지 않음.
list.add(obj) ;  // 여기서 경고 발생



@FunctionalInterface
- 함수형 인터페이스에 붙이면 컴파일러가 올바르게 작성했는지 체크함.
- 함수형 인터페이스는 하나의 추상메서드만 가져야 한다는 제약이 있음.

@FunctionalInterface // 하나의 추상 메서드만 사용 가능
public interface Runnable {
  public abstract void run(); // 추상메서드
}

 

표준 애너테이션 설명
@Override 컴파일러에게 오버라이딩하는 메서드라는 것을 알림
@Deprecated 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙임.
@SuppressWarnings 컴파일러의 특정 경고메세지가 나타나지 않게 해줌.
@SafeVarargs 지네릭스 타입의 가변인자에 사용함.(JDK 1.7)
@FunctionalInterface 함수형 인터페이스라는 것을 알림. (JDK 1.8)
@Native native 메서드에서 참조되는 상수 앞에 붙임. (JDK 1.8)

 

 

 

 

 

메타 애너테이션

  • '애너테이션을 위한 애너테이션'
  • 애너테이션을 만들 때 사용하는 애너테이션
  • 메타 애너테이션은 java.lan.annotation 패키지에 포함됨.
@Target
- 애너테이션을 정의할 때, 적용 대상 지정에 사용함.
- 오버라이딩을 올바르게 했는지 컴파일러가 체크하게 함.
- 오버라이딩 할 때 메서드 이름을 잘못 적는 실수 하는 경우가 많으니 사용해 볼 것.
@TARGET( {TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE} )
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
  String[] value();
}



@Retention
- 애너테이션이 유지되는 기간을 지정하는 데 사용함.
- 컴파일러에 의해 사용되는 애너테이션의 유지 정책은 SOURCE
- 실행 시에 사용 가능한 애너테이션의 정책은 RUNTIME

유지 정책 의미
SOURCE 소스 파일에만 존재
클래스 파일에는 존재하지 않음.
CLASS 클래스 파일에 존재
실행시에 사용불가, 기본값
RUNTIME 클래스 파일에 존재
실행시에 사용 가능
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}​

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FunctionalInterface {}​



@Documented
- javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙임.


@Inherited
- 애너테이션을 자손 클래스에 상속하고자 할 때 붙임

@Inherited  // SuperAnno가 자손까지 영양미치게 함.
@interface SuperAnno {}

@SuperAnno
class Parent {}

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



@Repeatable
- 반복해서 붙일 수 있는 애너테이션을 정의할 때 사용함.
- @Repeatable이 붙은 애너테이션은 반복해서 붙일 수 있음.
- @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션도 정의해야 함.

@Repeatable(ToDos.class) // ToDo 애너테이션을 여러 번 반복해서 사용
@interface ToDo {
  String value();
}

@ToDo("delete test codes.")
@ToDo("override inherited methods")

class MyClass {
  ...
}

@interface ToDos {  // 여러 개의 ToDo애너테이션을 담을 컨테이너 애너테이션 ToDos
  ToDo[] value(); // ToDo 애너테이션 배열타입의 요소 선언. 이름이 반드시 value여야 함.
}

 

메타 애너테이션 설명
@Target 애너테이션이 적용가능한 대상을 지정하는데 사용함.
@Documented 애너테이션 정보가 javadoc으로 작성된 문서에 포함되게 함.
@Inherited 애너테이션이 자손 클래스에 상속되도록 함.
@Retention 애터네이션이 유지되는 범위를 지정하는데 사용함.
@Repeatable 애터네이션을 반복해서 적용할 수 있게 함. (JDK 1.8)

 

 

 

 

 

애너테이션 타입 정의하기

  • 애너테이션을 직접 만들어 쓸 수 있음.
  • 애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정(순서 X)
  • 추상 메서드를 구현할 필요는 없음.
@interface 애너테이션이름 {
  타입 요소이름();  // 애너테이션의 요소 선언
     ...
}

@interface TestInfo {
  int count();
  String testedBy();
  String[] testTools();
  TestType testType(); // enum testType { FIRST, FINAL }
  DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime)을 포함할 수 있음.
}

@TestInfo (
  count=3, testedBy = "Kim",
  testTool = ("JUnit", "AutoTester"),
  testType = TestType.FIRST,
  testDate=@DateTime(yymmdd="221111", hhmmss = "111111")
}
public class NewClass {...}

 

 

 

 

 

애너테이션의 요소

  • 적용 시 값을 지정하지 않으면 사용될 수 있는 기본값 지정 가능(null 제외)
  • 요소가 하나이고 이름이 value일 때 요소의 이름 생략 가능.
  • 요소의 타입이 배열인 경우, 괄호{}를 사용해야 함.
@interface TestInfo {
  int count() default 1;
}

@TestInfo
public class NewClass {...}


@interface TestInfo {
  String value();
}

@TestInfo("passed")
class NewClass {...}


@interface TestInfo {
  String[] testTools();
}

@Test(testTools={})

 

 

 

 

 

애너테이션의 조상

  • java.lang.annotation.Annotation.
  • Annotation은 모든 애너테이션의 조상이지만 상속은 불가능함.
  • Annotation은 인터페이스임.
@interface TestInfo extends Annotation { // 에러. 허용되지 않는 표현
}

package java.lang.annotation;

public interface Annotation { // Annotation 자신은 인터페이스임.
  boolean equals(Object obj);
  int hashCode();
  String toString();
  
  class<? extends Annotation> annotationType(); // 애너테이션 타입 반환
}

 

 

 

 

 

마커 애너테이션(Marker Annotation)

  • 요소가 하나도 정의되지 않은 애너테이션
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}  // 마커 애너테이션. 정의된 요소가 하나도 없음.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {}  // 마커 애너테이션. 정의된 요소가 하나도 없음.

 

 

 

 

 

애너테이션 요소의 규칙

  • 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용됨.
  • 괄호() 안에 매개변수 선언 불가능 - 추상 메서드
  • 예외 선언 불가능
  • 요소를 타입 매개변수로 정의할 수 없음. <T>

 

 

 

 

 

 

 

 

 

 


🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.

 

저작자표시 비영리 변경금지 (새창열림)
'Back-End/Java' 카테고리의 다른 글
  • [JAVA] 람다식
  • [JAVA] 스레드
  • [JAVA] 열거형
  • [JAVA] 지네릭스
뚜비
뚜비
1년차 백엔드&iOS 개발자의 감자 탈출 블로그 🥔🥔
  • 뚜비
    뚜비의 개발로그
    뚜비
  • 전체
    오늘
    어제
  • 글쓰기     관리
    • Devlog
      • Back-End
        • Java
        • Spring
        • JPA
        • HTTP
        • Security
        • Back-End
        • Front-End
      • 알고리즘
      • iOS
        • Swift
      • Database
      • Tips
        • Git & GitHub
        • A to Z
      • 프로젝트
      • 생각정리
  • 태그

    김영한
    생성자
    HTTP
    DB
    MVC
    Java
    게시판만들기
    데이터베이스
    자바스크립트
    javascript
    백준
    Security
    의존성주입
    Spring Security
    객체
    프로그래머스
    변수
    html
    다형성
    최주호
    sql
    스프링
    자바
    성능최적화
    jsp
    JPA
    알고리즘
    spring
    Swift
    Database
  • hELLO· Designed By정상우.v4.10.0
뚜비
[JAVA] 애노테이션
상단으로

티스토리툴바