1일차 미션(어노테이션)
맨 아래에 미션 내용이 있습니다.
(미션을 하면서 학습한 내용을 함께 작성하였습니다.)
Annotations
어노테이션은 메타데이터의 형태로 프로그램에 대한 데이터를 제공한다. 어노테이션은 코드의 작동에 직접적인 영향을 미치지 않는다.
어노테이션은 다음과 같은 사용을 한다.
- 컴파일러에게 정보 제공 - 어노테이션은 컴파일러가 에러나 경고를 막기위해 사용된다. 
- 컴파일 시 및 배포 시 처리 - 소프트웨어 도구는 어노테이션 정보를 가지고 코드, XML 파일 등을 생성할 수 있다. 
- 런타임 처리 - 일부 어노테이션은 런타임 시(실행 시) 확인될 수 있고, 이를 기반으로 추가적인 동작이나 처리를 수행할 수 있다. 
Annotation 기본사항
- @Annotation 형태 
- @는 뒤에 오는 내용이 어노테이션임을 컴파일러에게 나타낸다. 
- element가 한개인 경우 name을 생략할 수 있다. element가 없는 경우 @Override처럼 괄호를 생략할 수 있다. - @Author( name = "Benjamin Franklin", date = "3/27/2003" ) class MyClass { ... } or @SuppressWarnings(value = "unchecked") void myMethod() { ... } @SuppressWarnings("unchecked") void myMethod() { ... }
- 여러개의 어노테이션을 사용할 수 있다. - @Author(name = "Jane Doe") @EBook class MyClass { ... }
- 같은 타입을 가지는 어노테이션들을 repeating 어노테이션이라 한다. 자바 8버전부터 지원 - @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }
어디서 어노테이션이 사용되는가?
- 어노테이션은 클래스, 필드, 메소드, 다른 프로그램의 요소 선언에 적용될 수 있다. 
- 클래스 객체 생성 표현식 (new @Interned MyObject(); ) , 형변환, implements 절, 발생한 예외 선언 절에서도 사용된다. 이러한 형태의 어노테이션은 “타입 어노테이션”이라 한다. 자바 8에서 생겨남 
어노테이션 타입 선언
어노테이션으로 코드 내의 주석들을 대체할 수 있다.
예를들어서 ‘모든 클래스 시작에 아래와 같이 중요한 주석들을 단다’ 라는 규칙이 있다고 생각해보자.
public class Generation3List extends Generation2List {
   // Author: John Doe
   // Date: 3/17/2002
   // Current revision: 6
   // Last modified: 4/12/2004
   // By: Jane Doe
   // Reviewers: Alice, Bill, Cindy
   // class code goes here
}
To add t
어노테이션으로 동일한 내용의 메타데이터를 추가하기 위해서는, 사전에 아래와 같은 문법을 사용해서 어노테이션 타입을 정의해야한다.
@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}
- 어노테이션 선언 시 interface 키워드 앞에 @를 붙여야한다. 
- 어노테이션 타입은 인터페이스 형태이다. 
- 메소드와 비슷하게 어노테이션 타입 요소 선언이 포함되어있다. 이 때 기본값을 정의할 수 있다. 
- 어노테이션을 정의하면 아래와 같이 사용가능하다. 
@Documented : // 만약에 javadoc에 포함시키고싶으면 해당 어노테이션 추가
@ClassPreamble (
   author = "John Doe",
   date = "3/17/2002",
   currentRevision = 6,
   lastModified = "4/12/2004",
   lastModifiedBy = "Jane Doe",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {
// class code goes here
}
미리 선언된 어노테이션 타입들
- 자바 언어에서 사용되는 어노테이션 - @Deprecated 
- @Override 
- @SuppressWarnings (컴파일러가 생성할 특정 경고 억제) 
- @SafeVarargs 
- @FunctionalInterface 
 
- 다른 어노테이션에 적용되는 어노테이션 : 메타 어노테이션 - @Retention 
- @Documented 
- @Target 
- @Inherited 
- @Repeatable 
 
Type Annotations and Pluggable Type Systems
- 자바 8 이전에는 어노테이션을 선언에만 적용 가능 
- 이후에는 어떤 타입 사용에도 적용 가능 
반복 어노테이션
- 동일한 어노테이션을 한 선언 또는 타입에서 여러번 사용 
- ex) 타이머 서비스를 사용하는 코드에서 특정 메소드를 매월 마지막 날, 매주 금요일 오후 11시에 실행하도록 타이머를 설정하기 위해 @Schedule 어노테이션 두번 사용 - @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... }
- 사용법 - 반복 가능한 어노테이션 타입 선언 
 - import java.lang.annotation.Repeatable; @Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; }- 컨테이닝 어노테이션 타입 선언 : @Schedules어노테이션은 Schedule 어노테이션을 array로 저장할 수 있는 value 요소를 가져야함 
 - public @interface Schedules { Schedule[] value(); }
Lesson: Annotations (The Java™ Tutorials > Learning the Java Language)
- 어노테이션을 직접 만들어 쓸 수 있다. - @interface 어노테이션이름{ 타입 요소이름(); // 어노테이션의 요소를 선언한다. ... } @interface DateTime{ String yymmdd(); String hhmmss(); }
- 어노테이션의 메서드는 추상 메서드이며, 어노테이션을 적용할 때 지정(순서 X) 추상 메서드는 구현할 필요가 없음 - @interface TestInfo{ int count(); String testedBy(); String[] testTools(); TestType testType(); // enum TestType { FIRST, FINAL } DateTime testDate(); //자신이 아닌 다른 어노테이션 포함 가능
- 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null제외) - @interface TestInfo{ int count() default 1; } @TestInfo public class newClass{ ... }
- 요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능 - @interface TestInfo{ String value(); } @TestInfo("passed") // @TestInfo(value="passed")와 동일 class newClass{ ... }
- 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다 - @interface TestInfo{ String[] testTools(); } @Test(testTools={"JUnit", "AutoTester"}) @Test(testTools="JUnit") @Test(testTools={}) // 값이 없을 때는 괄호{}가 반드시 필요
- 모든 어노테이션의 조상 - Annotation은 모든 어노테이션의 조상이지만 상속은 불가 
- 사실 Annotation은 인터페이스다. 
 
- 마커 어노테이션 - 요소가 하나도 정의되지 않은 어노테이션 
- @Test, @Deprecated 
 
- 어노테이션 요소의 규칙 - 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용 
- 추상메서드의 괄호 ()안에 매개변수를 선언할 수 없다 
- 예외를 선언할 수 없다 
- 요소를 타입 매개변수로 정의할 수 없다. - <T>
 
[자바의 정석 - 기초편] ch12-23,24 애너테이션
실제로 직접 만들어서 사용할만한 어노테이션에는 뭐가 있을까?
- 프로젝트를 하지 않아서 실제로 어떨 때 필요할 지 와닿지 않음 
- 지피티에게 물어본 결과 
- @JsonField:- 해당 필드가 JSON 직렬화/역직렬화 대상임을 나타내는 어노테이션. 
 - javaCopy code public class MyObject { @JsonField private String name; @JsonField private int age; // ... }
- @NotNull:- 매개변수나 필드가 null이 아니어야 함을 나타내는 어노테이션. 
 - javaCopy code public void someMethod(@NotNull String parameter) { // 메서드 로직 }
- @RetryOnFailure:- 메서드나 함수가 실패할 경우 지정된 횟수만큼 자동으로 재시도하도록 하는 어노테이션. 
 - javaCopy code @RetryOnFailure(maxAttempts = 3) public void someOperation() { // 작업 로직 }
- @LogPerformance:- 메서드의 실행 시간을 로그에 기록하는 어노테이션. 
 - javaCopy code @LogPerformance public void performanceCriticalMethod() { // 성능 중요한 작업 로직 }
- @SecureAccess(role = "ADMIN"):- 특정 역할이나 권한을 요구하는 보안 접근을 나타내는 어노테이션. 
 - javaCopy code @SecureAccess(role = "ADMIN") public void adminOnlyOperation() { // 관리자 권한이 필요한 작업 로직 }
이러한 예시처럼 프로젝트의 특정 요구사항에 맞게 어노테이션을 설계하고 사용할 수 있습니다. 직접 만든 어노테이션을 사용하면 코드의 가독성을 높이고 개발자들 간의 일관성을 유지할 수 있습니다.
어노테이션을 사용하는 이유 (효과) 는 무엇일까?
개발자 관점에서 @Override와 같은 어노테이션을 사용하면 해당 메서드가 상위 클래스에서 오버라이드 된 것임을 확실하게 알 수 있다. 즉 코드를 읽을때 유용하고 의도를 명확하게 전달할 수 있다.
컴파일러 관점에서 컴파일러가 @Override어노테이션 정보를 통해 상위 클래스에 해당 메서드가 존재하는지 확인하고, 아니면 오류를 발생시킬 수 있다. 즉
즉 어노테이션은 개발자에게 코드 작성 시 명확한 정보를 제공하고, 컴파일러에게는 코드의 일관성과 정확성을 검증할 수 있는 수단으로 활용된다.
<gpt>
자바에서 어노테이션(Annotation)은 코드에 메타데이터를 추가하는 방법으로 사용됩니다. 어노테이션은 주석과는 다르게 컴파일러나 런타임 시에 코드에 대한 정보를 제공하며, 다양한 목적으로 활용됩니다. 몇 가지 주된 이유는 다음과 같습니다:
- 코드 문서화 및 가독성 향상: 어노테이션을 사용하면 코드에 추가적인 정보를 주석으로 달지 않고도 문서화할 수 있습니다. 예를 들어, - @Deprecated어노테이션은 해당 메서드나 클래스가 더 이상 권장되지 않음을 나타냅니다.
- 컴파일 타임 체크: 일부 어노테이션은 컴파일러에게 특정 경고나 오류를 생성하도록 알려줄 수 있습니다. 예를 들어, 널 포인터 예외를 방지하기 위해 사용되는 - @NonNull어노테이션 등이 있습니다.
- 런타임 처리와 리플렉션: 몇몇 어노테이션은 런타임에 정보를 검색하거나 특정 동작을 수행할 수 있도록 해줍니다. 예를 들어, 스프링 프레임워크에서는 - @Autowired어노테이션을 사용하여 의존성 주입을 수행합니다.
- 프레임워크와 라이브러리 통합: 어노테이션은 프레임워크나 라이브러리에서 특정 기능을 활성화하기 위한 힌트로 사용됩니다. 예를 들어, JUnit에서는 - @Test어노테이션을 사용하여 테스트 메서드를 식별하고 실행합니다.
- 커스텀 마커 어노테이션: 프로그래머가 자신만의 어노테이션을 정의하여 특정 상황에 대한 힌트를 추가하거나, 프레임워크에서 사용할 수 있는 커스텀 마커로 활용할 수 있습니다. 
이러한 이유로 어노테이션은 자바의 다양한 분야에서 사용되며, 코드의 가독성과 유지보수성을 향상시키고 추가적인 기능을 제공합니다.
나만의 어노테이션은 어떻게 만들 수 있을까?
- @interface키워드를 사용하여 어노테이션을 정의한다 
- 요소를 정의한다 : 필요한 속성이나 요소 정의하고 기본값 설정 
- 적용한 어노테이션을 다른 코드에서 적용하여 사용하며, 필요한 경우 리플렉션을 활용하여 어노테이션의 정보를 읽을 수 있다. 
MyAnnotation.interface
package com.group.libraryapp.annotationTest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String name();
    String value() default "value의 기본 값";
}
package com.group.libraryapp.annotationTest;
public class Class {
    @MyAnnotation(name = "비둘기",value = "pigeon")
    public void doThis(){
    }
    @MyAnnotation(name = "pigeon")
    public void doThat(){
    }
}
package com.group.libraryapp.annotationTest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class MethodAnnotationExecutor {
    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Class.class.getMethod("doThis");
        Annotation[] annotations = method.getDeclaredAnnotations();
        for(Annotation annotation : annotations){
            System.out.println(annotation);
            if(annotation instanceof MyAnnotation){
                MyAnnotation myAnnotation = (MyAnnotation) annotation;
                System.out.println("name : " + myAnnotation.name());
                System.out.println("value : " + myAnnotation.value());
            }
        }
    }
}
댓글을 작성해보세요.
