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
- etf
- javascript
- 제태크
- 금리인상
- 배당성장
- 알고리즘
- 주식
- object
- S&P500
- 금리인하
- Java
- 그리디 알고리즘
- 무디스
- 자바
- 오버라이딩
- StringBuffer
- 미국주식
- 현금흐름표
- 인플레이션
- 기업분석
- mco
- 다형성
- 프로그래머스
- 객체지향
- 잉여현금흐름
- 백준
- 주린이
- FCF
- XLF
- 접근제어자
Archives
- Today
- Total
오늘의하루
[Java] 표준, 메타 Annotation(애너테이션) 본문
반응형
Java에서 제공하는 애너테이션에는 표준 애너테이션과 메타 애너테이션이 있습니다.
애너테이션 종류
표준 애너테이션 | 설명 |
@Override | 컴파일러에게 오버라이딩하는 메서드라는 것을 알린다. |
@Deprecated | 사용하지 않을 것을 권장하는 대상에 붙인다. |
@SuppressWarnings | 컴파일러의 특정 경고를 나타나지 않게 해준다. |
@SafeVarargs | 제네릭 타입의 가변인자에 사용한다. |
@FunctionalInterface | 함수형 인터페이스라는 것을 알린다. |
@Native | native메서드에서 참조되는 상수 앞에 붙인다. |
메타 애너테이션 | 설명 |
@Target* | 애너테이션이 적용가능한 대상을 지정한다. |
@Documented* | 애너테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다. |
@Inherited* | 애너테이션이 자식 클래스에 상속되도록 한다. |
@Retention* | 애너테이션이 유지되는 범위를 지정하는데 사용 |
@Repeatable* | 애너테이션을 반복해서 적용할 수 있게 한다. |
표준 - @Override
오버 라이딩을 올바르게 작성했는지 컴파일러가 체크를 하며, 오타 같은 실수를 잡아주는 역할을 한다.
class Parent{
void parentMethod(){}
}
class Child extends Parent{
void PARENTMETHOD(){} // 오버라이딩하려 했으나 오타가 발생
}
- 오버 라이딩할 때는 메서드 선언부 앞에 @Override를 붙이면 사용할 수 있다.
class Parent{
void parentMethod(){}
}
class Child extends Parent{
@Override
void PARENTMETHOD(){} // Error!!!
@Override
void parentMethod(){} // OK
}
표준 - @Deprecated
앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.
class Test{
@Deprecated
int x;
@Deprecated
public int getTest(){}
}
- @Deprecated가 붙은 대상이 사용된 코드를 컴파일하면 나타나는 메시지이다.
- Note : Annotation파일명 uses or overrides a deprecated API.
- Note : Recompile with -Xlint:deprecation for details.
표준 - @FunctionalInterface
함수형 인터페이스에 붙이면 컴파일러가 올바르게 작성했는지 체크해준다.
- 함수형 인터페이스는 하나의 추상 메서드만 가져야 한다는 제약이 있다.
@FuntionalInterface
interface Test{
abstract void getTest(); // 추상메서드
}
@FuntionalInterface
interface Test{ // Error! 함수형 인터페이스는 추상메서드가 1개만 있어야한다.
abstract void getTest(); // 추상메서드
abstract void setTest(); // 추상메서드
}
표준 - @SuppressWarnings
컴파일러의 경고 메시지가 나타나지 않게 억제한다.
사용방법
- 괄호() 안에 억제하고자 하는 경고의 종류를 문자열로 지정한다.
@SuppressWarnings("unchecked") // 제네릭스와 관련된 경고를 억제
ArrayList list = new ArrayList(); // 제네릭 타입을 지정하지 않았음
list.add(obj); // 경고 발생
- 두 개 이상의 경고를 동시에 억제할 때는 배열처럼 작성한다.
@SuppressWarnings({"deprecation", "unchecked", "varargs"})
- "-Xlint"옵션으로 컴파일하면 경고 메시지를 볼 수 있다.
메타 - @Target
애너테이션을 만들기 위한 애너테이션이며 애너테이션을 적용할 수 있는 대상을 지정한다.
대상타입 | 의미 | 대상타입 | 의미 |
ANNOTATION_TYPE | 애너테이션 | PACKAGE | 패키지 |
CONSTRUCTOR | 생성자 | PARAMETER | 매개변수 |
FIELD | 필드 (멤버변수, enum상수) |
TYPE | 타입 (클래스, 인터페이스, enum) |
LOCAL_VARIABLE | 지역변수 | TYPE_PARAMETER | 타입 매개변수 |
METHOD | 메서드 | TYPE_USE | 타입이 사용되는 모든 곳 |
@Target({TYPE, FIELD, METHOD}) // 타입, 메서드, 멤버변수에 사용할 수 있다.
public @interface MyAnnotation{} // MyAnnotation 애너테이션 생성
메타 - @Retention
애너테이션이 유지되는 기간을 지정하는 데 사용한다.
유지정책 | 의미 |
SOURCE | 소스 파일에만 존재, 클래스파일에는 존재하지 않는다. |
CLASS | 클래스 파일에 존재, 실행시에 사용불가 (기본값) |
RUNTIME | 클래스 파일에 존재, 실행시에 사용가능 |
컴파일러에 의해 사용되는 애너테이션의 유지 정책은 SOURCE이다
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{}
실행 시에 사용 가능한 애너테이션의 정책은 RUNTIME이다.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FuntionalInterface{}
메타 - @Documented, @Inherited
javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙인다.
@Document
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface{}
애너테이션을 자식 클래스에 상속하고자 할 때 @Inherited를 붙인다.
@Inherited // @SupperAnno가 자식까지 영향을 미친다.
@interface SupperAnno{}
@SuperAnno
class Parent{}
class Child extends Parent{} // Child에 SupperAnno애너테이션이 붙은 것으로 인식
메타 - @Repeatable
반복해서 붙일 수 있는 애너테이션을 정의하는 데 사용한다.
@Repeatable(ToDos.class) // ToDo 애너테이션을 여러번 사용할 수 있다.
@interface ToDo{
String value();
}
사용하는 방법
@ToDo("delete test codes.")
@ToDo("override inherited methods")
@ToDo("Message write~")
class Myclass{}
애너테이션 타입 정의하기
애너테이션을 직접 만들어서 사용할 수 있다.
@interface 애너테이션 이름{
타입 요소이름(); // 애너테이션 요소를 선언한다.
}
애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 모두 지정해야 한다. (순서 상관없음)
enum TestType {FIRST, FIANL}
@interface TestInfo{
int count();
String testBy();
String[] testTools();
TestType testType();
DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime)을 포함할 수 있다.
}
위에서 만든 애너테이션을 사용해보기
@TestInfo(
count = 3, testedBy = "Kim",
testTools = {"JUnit", "AutoTester"},
testType = TestType.FIRST,
testDate = @DateTime(yymmdd = "160101", hhmmss = "235959")
)
public class NewClass{...}
애너테이션의 요소
- 애너테이션을 적용 시 값을 지정하지 않았을 경우 사용할 수 있는 기본값을 지정 가능하다.
@interface TestInfo{
int count() default 1; // 기본 값을 1로 지정한다.
}
위 애너테이션을 사용해보기
@TestInfo // @TestInfo(int count = 1)과 동일하다.
public class NewClass{...}
- 요소가 하나이고 해당 요소의 이름이 value일 경우 생략이 가능하다.
@interface TestInfo{
String value();
}
위 애너테이션을 사용해보기
@TestInfo("passed") // @TestInfo(value = "passed")와 동일하다.
class NewClass{...}
- 요소의 타입이 배열인 경우 괄호{ }를 사용해야 한다.
@interface TestInfo{
String[] testTools();
}
위 애너테이션을 사용해보기
@TestInfo(
testTools = {"JUnit", "AutoTester"} // 배열이 2개 이상일 경우
)
@TestInfo(
testTools = "JUnit" // 배열이 1개일 경우
)
@TestInfo(
testTools = {} // 배열의 값이 없어도 괄호{}를 반드시 해줘야한다.
)
모든 애너테이션의 조상 Annotation
Annotation은 모든 애너테이션의 조상이지만 상속은 불가능하다.
@interface TestInfo extends Annotation{ // Error! 허용되지 않는 표현
int count();
}
마커 애너테이션
요소가 하나도 정의되지 않은 애너테이션을 의미한다.
- 예시로는 @Override, @Deprecated 등등
애너 테이션 요소의 규칙
애너테이션의 요소를 선언할 때 아래의 규칙을 반드시 지켜야 한다.
- 요소의 타입은 기본형, String, enum, 애너테이션, Class(설계도)만 허용된다.
- 괄호( ) 안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없다.
- 요소를 타입 매개변수로 정의할 수 없다.
// Quiz
@interface AnnoTest{
int id = 100; // OK 상수
String major(int i, int j); // Error! 매개변수 사용 불가
String minor() throws Exception; // 예외 선언 불가
ArrayList<T> list(); // 타입 매개변수 정의 불가
}
예제를 통해 복습하기
import java.lang.annotation.*;
@Deprecated // 사용 중지 권장
@SuppressWarnings("1111") // 유효하지 않은 애너테이션이고 이런 애너테이션은 무시된다.
@TestInfo(
testedBy = "aaaa",
testDate = @DateTime(yymmdd = "160101", hhmmss = "235959")
// 나머지도 적어줘야하지만 default 값이 있기 때문에 생략이 가능하다.
)
public class Myclass{
public static void main(String[] args){
Class<Myclass> cls = Myclass.class;
// Myclass의 Class객체를 얻는다.
TestInfo anno = cls.getAnnotation(TestInfo.class);
System.out.println("anno.testedBy() = " + anno.testedBy()); // aaaa
System.out.println("anno.testDate().yymmdd() = " + anno.testDate().yymmdd());
// 160101
System.out.println("anno.testDate().hhmmss() = " + anno.testDate().hhmmss());
// 235959
for(String str : anno.testTools()){
System.out.println("testTools = " + str); // JUnit
}
System.out.println();
Annotation[] annoArr = cls.getAnnotations();
for (Annotation a : cls.getAnnotations()){
System.out.println(a);
}
// @java.lang.Deprecated(forRemoval=false, since="")
// @TestInfo(count=1, testType=First, testTools={"JUnit"},
testedBy="aaaa", testDate=@DateTime(yymmdd="160101",
hhmmss="235959"))
}
}
enum TestType{First, Final}
@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();
}
반응형
'JAVA' 카테고리의 다른 글
[Java] 변수, 연산자, 조건문, 반복문, 배열, 객체지향, 예외처리 (0) | 2022.09.13 |
---|---|
[Java] Process & Thread (프로세스와 스레드) 알아보기 (0) | 2022.09.05 |
[Java Note] Generics(제네릭스) 선언 정의 제한 형 변환 와일드 카드 (0) | 2022.08.31 |
[Java] Enum (열거형), Annotation (애너테이션) (0) | 2022.08.31 |
[Java] 비트 연산자(AND)로 홀수 짝수 구분하기 (0) | 2022.08.30 |
Comments