Programming/Java

F012 - Annotation

osean 2021. 5. 24. 03:11
✍️ μžλ°”μ˜ μ‹  ν›„λ°˜λΆ€μ— Annotation에 λŒ€ν•΄μ„œ κ³΅λΆ€ν–ˆλ‹€.
3μ£Όμ°¨ λ©˜ν† λ§ 쀑, λ©˜ν† λ‹˜κ»˜μ„œ Lombok이 μš°λ¦¬κ°€ μž‘μ„±ν•œ μ†ŒμŠ€μ½”λ“œμ— μ–΄λ–»κ²Œ κ°œμž…ν•˜λŠ”μ§€ μ—¬μ­€λ³΄μ…¨λŠ”λ° μ‘μš©μ΄ λ˜μ§€ μ•Šμ•„μ„œ λŒ€λ‹΅λ„ λͺ»ν•˜λŠ” 꿀먹은 벙어리가 λ˜μ—ˆλ‹€.
이번 μ‹œκ°„μ—λŠ” Annotation에 λŒ€ν•΄μ„œ κ°„λ‹¨νžˆ μ •λ¦¬ν•΄λ³΄μž!

Annotation

μ–Όλ§ˆ μ „ κ³΅λΆ€ν•œ λ‚΄μš© 쀑, @Override Annotation(μ΄ν•˜ μ–΄λ…Έν…Œμ΄μ…˜)에 λŒ€ν•΄μ„œ κ³΅λΆ€ν–ˆλ‹€. @Override μ–΄λ…Έν…Œμ΄μ…˜μ€ λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ μ •μ˜ν•œ μƒμ„±μž ν˜Ήμ€ λ©”μ†Œλ“œλ₯Ό μƒμ†λ°›λŠ” μžμ‹ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜ ν•  λ•Œ, ν•΄λ‹Ή μƒμ„±μž ν˜Ήμ€ λ©”μ†Œλ“œλŠ” μž¬μ •μ˜λœ μƒνƒœν•˜λŠ” 것이라고 λͺ…μ‹œμ μœΌλ‘œ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.

ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ˜ μ†ŒμŠ€μ½”λ“œλ₯Ό 확인해보면, @Override μ–΄λ…Έν…Œμ΄μ…˜μ€ 1. λ©”μ†Œλ“œ μ˜μ—­μ—μ„œ μ‚¬μš© ν•  수 있으며 2. μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ 컴파일 μ‹œ μ†ŒμŠ€μ½”λ“œμ—μ„œ μ œκ±°λœλ‹€.

package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

 

πŸ”Ž λ©”μ†Œλ“œ μ˜μ—­μ—μ„œ μ‚¬μš©κ°€λŠ₯ν•˜λ‹€. → @Target(ElementType.METHOD)

πŸ”Ž μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ 컴파일 μ‹œ μ†ŒμŠ€μ½”λ“œμ—μ„œ μ œκ±°λœλ‹€. → @Retention(RetentionPolicy.SOURCE)

@Override μ–΄λ…Έν…Œμ΄μ…˜μ€ Javaμ—μ„œ κΈ°λ³Έ μ œκ³΅ν•΄μ£ΌλŠ” 3 가지 μ–΄λ…Έν…Œμ΄μ…˜ 쀑 ν•˜λ‚˜μΈλ°, μœ„μ˜ μ½”λ“œλ₯Ό 톡해 μ΄λŸ¬ν•œ κΈ°λ³Έ μ–΄λ…Έν…Œμ΄μ…˜λ„ @Targe, @Retention 같은 μ–΄λ…Έν…Œμ΄μ…˜ 섀정을 μœ„ν•œ μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ μ„€μ •λ˜μ–΄ μžˆλŠ” 것을 확인 ν•  수 μžˆλ‹€. μ΄λŸ¬ν•œ μ–΄λ…Έν…Œμ΄μ…˜μ€ Meta Annotation이라고 ν•œλ‹€.

Annotation 뽑아먹기

πŸ“ μ–΄λ…Έν…Œμ΄μ…˜μ€ 메타 λ°μ΄ν„°λ‘œμ¨, 컴파일 κ³Όμ •κ³Ό μ‹€ν–‰ κ³Όμ • 쀑 ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 μ–΄λ–»κ²Œ 처리 ν•  것인지 λͺ…μ‹œν•˜λŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.

πŸ“ Javaμ—μ„œ 기본으둜 μ œκ³΅ν•˜λŠ” μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œλŠ” @Override, @Deprecated, @SuppressWarning 이 μ‘΄μž¬ν•˜λ©°, Java 7μ—μ„œ @SafeVarargs, Java 8μ—μ„œ @FunctionalInterface λ₯Ό μ§€μ›ν•œλ‹€.

Meta Annotation

Meata Annotation(μ΄ν•˜ 메타 μ–΄λ…Έν…Œμ΄μ…˜)μ΄λž€ μ–΄λ…Έν…Œμ΄μ…˜μ„ λ§Œλ“€κΈ° μœ„ν•œ 섀정을 λ„μ™€μ£ΌλŠ” μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ java.lang.annotation νŒ¨ν‚€μ§€ 내에 μœ„μΉ˜ν•΄μžˆμœΌλ©° μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ μžμ‹  λ˜ν•œ 메타 μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

μ΄λŸ¬ν•œ 메타 μ–΄λ…Έν…Œμ΄μ…˜μ€ μƒˆλ‘­κ²Œ λ§Œλ“€ μ–΄λ…Έν…Œμ΄μ…˜μ΄ 어디에 μ‚¬μš©λ μ§€, μ–΄λ–€ μ‹œμ μ—μ„œ μ μš©λ μ§€, API λ¬Έμ„œμ— 등둝을 할지 등을 μ„€μ • ν•  수 μžˆλ‹€. λ‹€μŒ 리슀트λ₯Ό 톡해 ν™•μΈν•΄λ³΄μž.

πŸ“ @Target
ElementType[]을 value κ°’μœΌλ‘œ 가지며, ν•΄λ‹Ή 배열을 톡해 ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ΄ 어디에 적용 κ°€λŠ₯ν•œμ§€ μ„€μ • ν•  수 μžˆλ‹€. ν•΄λ‹Ή 메타 μ–΄λ…Έν…Œμ΄μ…˜μ€ ν•˜λ‚˜μ˜ μ–΄λ…Έν…Œμ΄μ…˜μ—μ„œ μ—¬λŸ¬ 개의 타깃을 μ„€μ • ν•  수 μžˆλ‹€.

βœ”οΈ ElementType.TYPE : 클래슀, μΈν„°νŽ˜μ΄μŠ€ ν˜Ήμ€ μ΄λ„˜ νƒ€μž…μ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.FIELD : 클래슀 λ‚΄ ν•„λ“œμ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.METHOD : λ©”μ†Œλ“œμ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.CONSTRUCTOR : μƒμ„±μžμ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.PARAMETER : 맀개 λ³€μˆ˜ μΈμžμ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.LOCAL_VARIABLE : λ©”μ†Œλ“œ ν˜Ήμ€ μƒμž λ‚΄μ˜ 지역 λ³€μˆ˜μ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.ANNOTATION_TYPE : μ–΄λ…Έν…Œμ΄μ…˜ νƒ€μž…μ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.PACKAGE : νŒ¨ν‚€μ§€μ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.TYPE_PARAMETER : Java 8 λΆ€ν„° μΆ”κ°€λ˜μ–΄ νƒ€μž… νŒŒλΌλ―Έν„°μ— 적용 κ°€λŠ₯ν•˜λ‹€. 
βœ”οΈ ElementType.TYPE_USE : Java 8 λΆ€ν„° μΆ”κ°€λ˜μ–΄ ν•΄λ‹Ή νƒ€μž…μ΄ μ‚¬μš©λœλ‹€λŠ” 것을 λͺ…μ‹œν•œλ‹€.

πŸ“ @Retetion 
RetentionPolicy[]을 value κ°’μœΌλ‘œ 가지며, @Target μ–΄λ…Έν…Œμ΄μ…˜κ³Ό λ™μΌν•˜κ²Œ μ—¬λŸ¬ 개의 섀정값을 지정 ν•  수 μžˆλ‹€. ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ€ μ–΄λ–€ μ‹œμ μ— μ–΄λ…Έν…Œμ΄μ…˜μ„ μ μš©ν• μ§€ μ„€μ •ν•œλ‹€.

βœ”οΈ RetetionPolicy.SOURCE : μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μ μš©μ—μ„œ μ œμ™Έλœλ‹€. 
βœ”οΈ RetetionPolicy.CLASS : μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ .class 파일둜 컴파일 될 λ•Œ μ μš©λ˜μ§€λ§Œ Runtime μ‹œμ κΉŒμ§€λŠ” μœ νš¨ν•˜μ§€ λͺ»ν•œλ‹€. 
βœ”οΈ RetetionPolicy.RUNTIME : λ¦¬ν”Œλ ‰μ…˜μ— μ˜ν•΄ 컴파일 이후에도 μ§€μ†μ μœΌλ‘œ μ°Έμ‘°κ°€ κ°€λŠ₯ν•˜λ‹€.

πŸ“ @Documented 
ν•΄λ‹Ή 메타 μ–΄λ…Έν…Œμ΄μ…˜μ€ 적용된 μ–΄λ…Έν…Œμ΄μ…˜μ΄ μžλ°” API λ¬Έμ„œμ— 등둝될지λ₯Ό μ„€μ • ν•  수 μžˆλ‹€.

πŸ“ @Inherited 
ν•΄λ‹Ή 메타 μ–΄λ…Έν…Œμ΄μ…˜μ€ 적용된 μ–΄λ…Έν…Œμ΄μ…˜μ— μƒμ†μ˜ κΈ°λŠ₯ 뢀여에 λŒ€ν•œ 섀정을 λ‹΄λ‹Ήν•œλ‹€.

πŸ“ @Repeateble
Java 8 λΆ€ν„° μΆ”κ°€λ˜μ–΄ μ—°μ†μ μœΌλ‘œ μ–΄λ…Έν…Œμ΄μ…˜μ„ 적용 ν•  수 μžˆλ„λ‘ μ§€μ›ν•œλ‹€.

Custom Annotation

package annotation;

import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@Inherited
public @interface Auth {
    String name();

    String date();

    String description();
}

/*
	@Auth(name = "μ‹¬μ„±ν—Œ", date = "2021-05-24", description = "μ»€μŠ€ν…€ μ–΄λ…Έν…Œμ΄μ…˜μ„ λ§Œλ“€μ–΄λ³΄μž!")
    public class AnnotationTest {}
*/

πŸ€– 이번 μ‹œκ°„μ—λŠ” Lombok λ””μ»΄νŒŒμΌμ„ μ•Œμ•„λ³΄κΈ° μœ„ν•΄ Annotation이 μ–΄λ–»κ²Œ κ΅¬μ„±λ˜κ³  λ§Œλ“€μ–΄μ§€λŠ”μ§€ μ•Œμ•„λ³΄μ•˜λ‹€. λ‹€μŒ μ‹œκ°„μ—λŠ” μš°λ¦¬κ°€ 주둜 μ‚¬μš©ν•˜λŠ” μ–΄λ…Έν…Œμ΄μ…˜λ“€μ΄ μ–΄λ–»κ²Œ λ™μž‘ν•˜λŠ”μ§€ μ•Œμ•„λ³΄μž!

'Programming > Java' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

F014 - List (ArrayList, LinkedList, Vector, Stack)  (0) 2021.05.30
F013 - Generic  (0) 2021.05.26
F011 - java.lang.ref  (0) 2021.05.19
F010 - System.out.println(), Logger  (0) 2021.05.19
F009 - Inheritance, Composition  (0) 2021.05.18