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());
}
}
}
}
댓글을 작성해보세요.