본문 바로가기

Java/Study

[JAVA] 백기선 라이브 스터디 12주차 Annotation

목표

자바의 애노테이션에 대해 학습하세요.

학습할 것 (필수)


1. 어노테이션을 사용하는 이유

javadoc.exe를 사용해 주석으로 부터 HTML문서를 생성할 수 있다.

이는 소스코드와 문서를 하나로 관리하는 것이 낫다고 생각하여 개발되었다.

package anno;

/**
 * Test Annotation
 * **/
public class DemoFunctionClass implements DemoFunctional {
    @Override
    public int printAge(int age) {
        return 0;
    }

    @Override
    public void testMessage() {
        System.out.println("디폴트 메서드만 수정이 가능하네요.");
    }


    public static void main(String[] args) {

intellj에서html문서를 생성해 보았다 (인코딩 설정 주의!)

 

javadoc.exe는 주석 안에 소스코드에 대한 설명이 있고, 그 안에 @이 붙은 태그를 읽어 문서를 작성한다.

이 기능을 응용하여 , 

주석처럼 프로그래밍 언어에 영향을 미치지 않으면서 유용한 정보를 제공하기 위해 사용된다.

 

2. 어노테이션의 종류

1. 표준 어노테이션 : 자바에서 기본적으로 제공

@Override

class A {
    public void systemOutPrintln(){
        System.out.println("in A");
    }
}
class B extends A{
    public void systemOutPrintLn(){// 오타가 났다고 가정해보자.
        System.out.println("in B");
    }
}
public class UsageOfOverride {
    public static void main(String[] args) {
        B obj = new B();
        obj.systemOutPrintln();
    }
}

@Override 어노테이션을 붙이면,

컴파일러가 같은 이름의 메서드가 조상에 있는지 확인하고 , 없으면 에러메세지를 출력한다.

-오타와 같은 실수를 미연에 방지한다.

 

@Deprecated

API에 많이 등장하는 어노테이션 

더 좋은 방법이 나와도 기존의 사용되던 것들을 함부로 삭제 할 수 없으므로 남겨둔다.

Calendar api을 사용을 권장하고 있음

@FunctionalInterface

함수형 인터페이스의 선언이 올바른지 확인해 주는 어노테이션

'함수형 인터페이스' 추상 메서드가 하나만 존재하는 인터페이스 ( JAVA 8에 default 와 static 메서드가 추가 되었다.)

 

@SupressWarnings

경고가 발생할 것을 알면서도 묵인해야 할 경우

--option:

              "unchecked" - generics로  타입을 지정하지 않았을 경우

              "rawtypes" - generics로  타입을 사용하지 않아서 발생하는 경우     


2. 메타 어노테이션 

메타 데이터 : 데이터를 설명하기 위한 데이터
메타 어노테이션 : 어노테이션을 설명하기 위한 어노테이션!

메타 어노테이션의 종류와 사용법

@Target : 어노테이션 적용가능 대상을 설정할 때 사용

import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;

@Target({FIELD, TYPE, TYPE_USE})
public @interface DemoTargetAnno {}
@DemoTargetAnno// 적용대상 TYPE
class TestClass{
    @DemoTargetAnno// 적용 대상 FIELD
    int i;
    @DemoTargetAnno// 적용 대상 TYPE_USE : TYPE이 사용되는 모든곳
    TestClass tc;
}

java.lang.annotaion.ElementType라는 열거형에 정의 되어있다.

 

@Retention : 어노테이션의 유지 기간 지정

유지 정책 의미
SOURCE                            -> 컴파일러가 사용하는 어노테이션 소스파일에만 존재. 클래스파일에는 x
CLASS 클래스 파일에 존재. 실행시 사용 불가 . DEFAULT
RUNTIME 클래스 파일에 존재. 실행시 사용 가능

 

실행시 Reflection을 통해 클래스 파일에 저장된 어노테이션을 통해 클래스 파일에 저장된 어노테이션 정보를 읽어서 처리한다.

- Reflection : 구체적인 클래스 타입을 알지 못해도 역으로 클래스에 대한 정보를 알아내어 클래스를 사용할 수 있는 방법

 

FunctionalInterface 의 RetnetionPolicy

@Dcoumented

javadoc으로 작성한 문서에 포함되도록 하는 어노테이션

 

@Inherited

조상 클래스에 붙이면, 자손 클래스도 붙은 것으로 인식한다.

 

@Repeatable

 @Repeatable 이 붙어있는 어노테이션은 여러번 붙일 수 있다.-> 하나로 묶어서 다룰 수 있는 어노테이션

import java.lang.annotation.Repeatable;

@interface Todos{
     Todo[] value();// 배열로 저장
}
@Repeatable(Todos.class)// 컨테이너 어노테이션 지정
public @interface Todo {
    String value();
}

어노테이션 정의 하는 방법

방법은 간단하다.

@interface MyInfo{
       int age() default 25; // 어노테이션의 요소를 선언한다. 원시데이터
       String name() ;
       String[] hobby();
       TestType testType(); // enum 형태를 요소로 갖는다.
       DateTime testDate(); //다른 어노테이션을 요소로 갖는다
}

default 25와 같이 기본값을 추가해 줄수 도 있다.

 

어노테이션 프로세서

소스코드 레벨에서 소스 코드에 붙어있는 어노테이션 정보를 읽어

컴파일 중 새로운 소스코드를 생성하거나 기존의 코드 변경을 가능하게 합니다.

 

장점

컴파일 시점에 조작하므로 런타임 비용이 제로

단점

기존의 코드를 고치는 방법으로 현재로서는 public 한 api가 없다 !