Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 자바의 정석 기초편 ch1
- 자바의 정석 기초편 ch4
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch2
- 코드로 시작하는 자바 첫걸음
- 2024 정보처리기사 수제비 실기
- 타임리프 - 기본기능
- 스프링 mvc2 - 로그인 처리
- 자바의 정석 기초편 ch6
- 스프링 db1 - 스프링과 문제 해결
- 자바의 정석 기초편 ch14
- 스프링 mvc2 - 검증
- 스프링 mvc1 - 서블릿
- 게시글 목록 api
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch5
- jpa - 객체지향 쿼리 언어
- 자바의 정석 기초편 ch12
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch9
- 2024 정보처리기사 시나공 필기
- 스프링 mvc1 - 스프링 mvc
- 스프링 고급 - 스프링 aop
- 스프링 db2 - 데이터 접근 기술
- @Aspect
- 자바의 정석 기초편 ch8
- jpa 활용2 - api 개발 고급
- 스프링 입문(무료)
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch11
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch12 - 23 ~ 37 [애노테이션, 표준애노테이션, 메타애노테이션, 애노테이션 타입 정의하기, 애노테이션의 요소] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch12 - 23 ~ 37 [애노테이션, 표준애노테이션, 메타애노테이션, 애노테이션 타입 정의하기, 애노테이션의 요소]
소소한나구리 2023. 12. 15. 11:551) 애노테이션
- 주석처럼 프로그래밍 언어에 영향을 미치지 않으며 유용한 정보를 제공함
- 특정 프로그램에 정보 제공을 위한 것(설정 정보 등)
- Annotation 은 인터페이스
- 애노테이션 사용 예시
2) 표준 애노테이션
- Java에서 제공하는 애노테이션의 종류
- 하얀색 - 표준애노테이션
- 갈색 - 매타애노테이션 : 애노테이션을 만들 때 사용
(1) @Override
- 오버라이딩을 올바르게 했는지 컴파일러가 체크하게 함
- 오버라이딩 할 때 메서드 이름을 잘못적는 실수를 하는 경우가 많은데 이를 방지할 수 있음
- 오버라이딩 할 때는 메서드 선언부 앞에 @Override를 붙이는 것을 권장
class Parent {
void parentMethod() {}
}
class Child extends Parent {
void parentmethod() {} // 오버라이딩 하려 했으나 실수로 이름을 잘못 적음
}
//Override 애노테이션 추가하여 오버라이딩이 제대로 되었는지 체크
class Child extends Parent {
@Override
void parentmethod() {} // 에러 발생. 조상의 메서드의 이름을 잘못적음
}
(2) @Deprecated
- 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙임
- @Deprecated의 사용 예시로 Date클래스의 getDate() 메서드가 있음
- @Deprecated가 붙은 대상이 사용된 코드를 사용하면 IDE 상에서 해당 코드에 줄이 그어지고 deprecated가 적용된 메서드가 있으니 컴파일하면 다시 컴파일하라는 메세지가 나타남(터미널에서 강제 컴파일)
@Deprecated
public int getDate() { // 사용을 권장하지 않음
return normalize(). getDayOfMonth();
}
(3) @FunctionalInterface
- 함수형 인터페이스에 사용함
- 함수형 인터페이스에는 하나의 추상메서드만 가져야 한다는 제약이 있는데 이를 올바르게 작성했는지 체크함
@FunctionalInterface // Override 애노테이션 처럼 함수형 인터페이스 작성시 작성을 권장
public interface Runnable {
public abstract void run (); // 추상메서드
}
@FunctionalInterface // 함수형 인터페이스인지 체크
interface Testable { // 함수형 인터페이스는 추상메서드를 1개만 가질 수 있음 -> 에러발생
void test(); // 추상메서드
void check(); // 추상메서드
}
(4) @SuppressWarnings
- 컴파일러의 경고메세지가 나타나지 않게 억제함
- 괄호()안에 억제하고자 하는 경고의 종류를 문자열로 지정할 수 있고 둘 이상의 경고를 동시에 억제할 수 있음
@SuppressWarnings("unchecked") // 제네릭스와 관련된 경고를 억제
// ArrayList = 제네릭클래스 ArrayList<T> 처럼 작성해야함
ArrayList list = new ArrayList(); // 제네릭 타입을 지정하지 않았음
list.add(obj); // 여기서 경고가 발생함
// 경고를 확인했다는 의미로 사용
// 둘이상의 경고를 동시에 억제
@SuppressWarnings({"deprecation", "unchecked", "varargs"})
// [deprecation] 경고 억제
class Ex12_7 {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
Child c = new Child();
c.parentMethod();
}
}
3) 메타 애노테이션
- 애노테이션을 위한 애노테이션으로 애노테이션을 정의할 때 사용함
- java.lang.annotation 패키지에 포함되어 있음
(1) @Target
- 애노테이션을 정의할 수 있는 적용할 대상을 지정할 때 사용
- ANNOTATION_TYPE : 애노테이션
- CONSTRUCTOR : 생성자
- FIELD : 필드(멤버변수, enum 상수)
- LOCAL_VARIABLE : 지역 변수
- METHOD : 메서드
- PACKAGE : 패키지
- PARAMETER : 매개변수
- TYPE : 타입(클래스, 인터페이스, enum)
- TYPE_PARAMETER : 타입 매개변수(JDK 1.8 이후)
- TYPE_USE : 타입이 사용되는 모든 곳 (JDK 1.8 이후)
import static java.lang.annotation.ElementType.*;
@Target({FIELD, TYPE, TYPE_USE}) // 적용 대상을 지정
public @interface MyAnnotation { } // MyAnnotation을 정의
@MyAnnotation // 적용 대상이 TYPE인 경우
class MyClass { // 클래스나 인터페이스
@MyAnnotation // 적용 대상이 FIELD인 경우
int i; // iv멤버변수
@MyAnnotation // 적용 대상이 TYPE_USE인 경우
MyClass me; // 참조변수
(2) @Retention
- 애노테이션이 유지(Retention)되는 기간을 지정하는데 사용, 즉 애노테이션의 생명주기를 설정
- 컴파일러에 의해 사용되는 애노테이션의 유지 정책은 SOURCE(소스파일에만 존재)
- 실행시에 사용 가능한 애노테이션의 정책은 RUNTIME(class파일에 존재)
- 기본정책은 CLASS(클래스 파일에 존재)
(3) @Documented, @Inherited
- javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙힘
- 애노테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙힘
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
@Inherited // @SuperAnno가 자손까지 영향 미치게
@interface SuperAnno {}
@SuperAnno
class Parent {}
class Child extends Parent {} // Child에 애너테이션 붙은 것으로 인식
(4) @Repeatable
- 반복해서 붙일 수 있는 애노테이션을 정의할 때 사용
- @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애노테이션도 정의해야 함
@Repeatable(ToDos.class)
@interface ToDo { // ToDo애노테이션을 여러 번 반복해서 쓸 수 있게 함.
String value();
}
// 애노테이션 반복 사용
@ToDo("delete test coded.")
@ToDo("override inherited methods")
class MyClass {
...
}
// 컨테이너 애노테이션 정의
@interface ToDos { // 여러개의 ToDo애노테이션을 담을 컨테이너 애노테이션
ToDo[] value(); // ToDo애노테이션 배열타입의 요소를 선언. 이름이 반드시 Value이어야 함
}
4) 애노테이션 타입 정의하기
- 애노테이션을 직접 만들어서 사용할 수 있음
- 애노테이션의 메서드는 추상메서드이므로 구현할 필요가 없으며 애노테이션을 적용할 때 각 추상메서드의 값을 지정하여 입력(입력하는 순서는 상관 없음)
(1) 애노테이션 정의 예시
// 애노테이션 정의방법
@interface 애노테이션이름 {
타입요소이름(); // 애노테이션의 요소를 선언
...
}
// 애노테이션 정의 예시
@interface TestInfo {
int count();
String testedBy();
String[] testTools();
TestType testType(); // enum TestType {FIRST, FINAL}, enum도 정의할 수 있음
DateTime testDate(); // 자신이 아닌 다른 애노테이션(@DateTime)을 포함할 수 있음
}
// 애노테이션 사용 -> 요소의 값들을 전부 적어야 함
@TestInfo(
count = 3, testedBy = "kim",
testTools = {"JUnit", "AutoTester"}, // 배열은 배열로 작성
testType = TestType.FIRST, // 열거형 지정
testDate = @DateTime(yymmdd="160101", hhmmss="235959")
)
public class NewClass { ... }
5) 애노테이션의 요소
- 적용시 값을 지정하지 않을 때 기본으로 사용될 수 있는 기본값을 지정할 수 있음(null 제외)
- 요소가 하나이고 이름이 value일 때는 요소의 이름을 생략할 수 있음
- 요소의 타입이 배열인 경우, 괄호{ }를 사용해야하며 마찬가지로 기본값을 적용할 수 있음
// 기본값을 지정할 수 있음
@interface TestInfo {
int count() default 1; // 기본값을 1로 지정
}
@TestInfo // 적용값을 생략했으므로 기본값이 적용 됨
public class NewClass {...}
---------------------------------
// 요소가 하나이고 이름이 value일 때는 요소의 이름을 생략할 수 있음
@interface TestInfo {
String value();
}
@TestInfo("passed") // @TestInfo(value = "passed")와 동일
public class NewClass {...}
---------------------------------
// 배열인 경우 괄호 {} 사용하여 요소의 값을 입력해야함
@interface Test{
String[] testTools();
}
@Test(testTools={"JUnit", "AutoTester"})
@Test(testTools={"JUnit"})
@Test(testTools={}) // 값이 없을 때에도 괄호{}가 반드시 필요
6) 모든 애노테이션의 조상 - java.lang.annotation.Annotation
- Annotation은 모든 애노테이션의 조상이지만 상속할 수 없음
- Annotation은 인터페이스
- 추상메서드들은 구현할 필요 없이 컴파일러가 자동으로 구현하기 때문에 사용가능함
(1) 마커 애노테이션 (Marker Annotation)
- 요소가 하나도 정의되지 않은 애노테이션
- 애노테이션이 붙어있는 것만으로도 충분한 정보를 제공함
(2) 애노테이션 요소의 규칙
- 애노테이션의 요소를 선언할 때는 규칙을 반드시 지켜야 함
- 요소의 타입은 기본형, String, enum, 애노테이션, class만 허용됨
- 괄호()안에 매개변수를 선언할 수 없음 (추상메서드안에 매개변수 작성 불가)
- 예외를 선언할 수 없음
- 요소를 타입 매개 변수로 정의할 수 없음 즉, 제네릭스사용이 불가능함
@interface AnnoTest {
int id = 100; // 상수 OK(인터페이스 처럼 static final 생략)
String majer(int i, int j); // 에러 : 매개변수 불가능
String minor() throws Exception; // 에러 : 예외선언 불가능
ArrayList<T> list(); // 에러 : 타입 매개변수 정의 불가능
}
(3) 애노테이션 예제
import java.lang.annotation.*;
@Deprecated
@SuppressWarnings("1111") // "1111" 경고는 무시
@TestInfo(testedBy="aaa", testDate=@DateTime(yymmdd="160101",hhmmss="235959"))
class Ex12_8 {
public static void main(String args[]) {
// Ex12_8의 Class객체를 생성
Class<Ex12_8> cls = Ex12_8.class;
TestInfo anno = cls.getAnnotation(TestInfo.class);
System.out.println("anno.testedBy()="+anno.testedBy());
System.out.println("anno.testDate().yymmdd()=" +anno.testDate().yymmdd());
System.out.println("anno.testDate().hhmmss()=" +anno.testDate().hhmmss());
for(String str : anno.testTools())
System.out.println("testTools="+str);
System.out.println();
//ex12_8에 적용된 모든 애노테이션을 가져온다.
Annotation[] annoArr = cls.getAnnotations();
for(Annotation a : annoArr)
System.out.println(a);
} // main의 끝
}
@Retention(RetentionPolicy.RUNTIME) // 실행 시에 사용가능하도록 지정
@interface TestInfo { // 애노테이션을 직접 정의
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
}
@Retention(RetentionPolicy.RUNTIME) // 실행 시에 사용가능하도록 지정
@interface DateTime { // 애노테이션을 직접 정의
String yymmdd();
String hhmmss();
}
enum TestType { FIRST, FINAL }
** 출처 : 남궁성의 정석코딩_자바의정석_기초편 유튜브 강의