์๋ฐ ์ด๋ ธํ ์ด์ (@Annotation)
by JiwonDev์๋ฐ์์ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ (@Annotation )์ ์ปดํ์ผ๋ฌ๋ฅผ ์ํ ์ผ์ข ์ ์ฃผ์์ผ๋ก, [๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๊ฑฐ๋ ์ฝ๋์ ์ํฅ์ ๋ฏธ์น์ง ์์ผ๋ฉฐ] ์ปดํ์ผ ๊ณผ์ ๊ณผ ์คํ๊ณผ์ ์์ ์ด๋ป๊ฒ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ & ์ปดํ์ผ์ ํด์ผ ํ๋์ง ์ ๋ณด๋ฅผ ์ค ์ ์๋ค.
๋ํ ๊ผญ ์ปดํ์ผ๋ฌ ์ค์ ์ด ์๋๋๋ผ๋, ์ํํธ์จ์ด ๊ฐ๋ฐ ํด์ด ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ฝ์ด ๋น๋ ๋๋ ๋ฐฐ์น์์ ํ์ํ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑํ ์ ์๋๋ก ๋ง๋ค ์ ์๋ค.
์ด๋ ธํ ์ด์ ์ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ์ ์๋ ์ด๋ฌํ ์ค์ ์ ๋ณด๋ฅผ XML๋ฑ์ผ๋ก ๋ฐ๋ก ๊ด๋ฆฌํ๋๋ฐ, ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉฐ ์๋ฐ ์์ค์ฝ๋์ ํจ๊ป ํฉ์ณ ํ๋๋ก ๊ด๋ฆฌ ํ ์ ์๊ฒ ๋์๋ค. ๋ํ @์ด๋ ธํ ์ด์ ์ ์ด์ฉํ๋ฉด ์ฝ๋์์ ์ค์ ์ ๋ณด๊ฐ ๋ช ํํ๊ฒ ๋ค์ด๋์ ๊ฐ๋ฐ์์ ์ค์๋ฅผ ์ค์ฌ์ค๋ค.
@AnnotationName
์ด๋ ธํ ์ด์ ์ ์๋ฐ์์ ์ ๊ณตํ๋ [ํ์ค ์ด๋ ธํ ์ด์ ]๊ณผ, @interface ํ๊ทธ๋ฅผ ์ด์ฉํด ์ด๋ ธํ ์ด์ ์ ์๋ก ๋ง๋ค ๋ ์ฌ์ฉ๋๋ [๋ฉํ ์ด๋ ธํ ์ด์ ]์ด ์๋ค.

# ์์ฃผ ์ฌ์ฉํ๋ ํ์ค์ด๋ ธํ ์ด์
@Override
์ค๋ฐ๋ผ์ด๋ฉ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ๋์ง, ์ปดํ์ผ ํ์์ ์ฒดํฌ๋ฅผ ํ๋ค.
class Parent { void myMethod(){~} } class Child extends Parent{ // ??? ์ค๋ฒ๋ผ์ด๋ฉ์ ํ๋ ค๋ค๊ฐ ์ค์๋ก ๋ค๋ฅธ ์ด๋ฆ์ ์์ฑํ์๋ค. // ํ์ง๋ง ์ปดํ์ผ๋ฌ ์
์ฅ์์๋ ์ด๊ฒ ์ค๋ฒ๋ผ์ด๋ฉ์ ํ๋ ค๊ณ ํ๊ฑด์ง ์ ์ ์๋ค. void myMetho(){~} }
class Child extends Parent{ @Override void myMetho(){~} // ์ปดํ์ผ ์๋ฌ! ๋ถ๋ชจ์๊ฒ ์กด์ฌํ์ง ์๋ ๋ฉ์๋ }
@Deprecated
์ด๋ฆ๋ง ๋ด๋ ์ ์ ์๋ฏ์ด, ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ ๊ถ์ฅํ๋ ์ ํ๋๋ ๋ฉ์๋์ ๋ถ์ธ๋ค. ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ญ์ ํ๋ฉด ๋์ง ์๋?๊ณ ์๊ฐํ ์ ์์ง๋ง ์๋ฐ์์๋ ๊ธฐ์กด ์ฑ์ ํ์ํธํ์ฑ์ ์ ๊ณตํ๊ธฐ ์ํด ํด๋น ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ค.
@Deprecated public int getDate(){ return normalize().getDayOfMonth(); }

@FunctionalInterface
ํจ์ํ ์ธํฐํ์ด์ค์ ์ฌ์ฉํ๋ฉฐ, ์ปดํ์ผ๋ฌ๊ฐ ํจ์ํ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑํ๋์ง ๋ฌธ๋ฒ์ ์ผ๋ก ํ์ธํ๋ค. (ํ๋์ ์ถ์๋ฉ์๋๋ง ๊ฐ์ง๊ณ ์๋๊ฐ?)
@SuppressWarnings("๊ฒฝ๊ณ ")
ํด๋น ๋ฉ์๋, ํ๋์ ๊ฒฝ๊ณ ๋ฉ์์ง๊ฐ ๋ํ๋๋ ์ปดํ์ผ๋ฌ๊ฐ ๋ฌด์ํ๋๋ก ์ค์ ํ๋ค. ์ฌ๋ฌ ๊ฐ๋ฅผ ๋ฌด์ํ๋ ค๋ฉด { "a", "b", "c" } ๋ก ์์ฑํ๋ค. ํด๋น ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉ์ผ๋ก ์ด ๊ฒฝ๊ณ ๋ฅผ ๊ฐ๋ฐ์๊ฐ ํ์ธํ์๊ณ , ์ค๋ฅ๊ฐ ์๋๋ผ๋ ๊ฒ์ ์๋ ค์ค ์ ์๋ค.
@SuppressWarnings("unchecked") ArrayList list = new ArrayList(); // ์ ๋ค๋ฆญ ํ์
์ ์ง์ ํ์ง ์์์ list.add(obj); // unchecked ๊ฒฝ๊ณ ๋ฐ์

# ์ง์ ๋ง๋ค๊ธฐ, ๋ฉํ ์ด๋ ธํ ์ด์
@interface ๋ฅผ ์ด์ฉํ์ฌ ํด๋์ค ์ ์ํ๋ฏ์ด ์๋ก์ด ์ด๋ ธํ ์ด์ ์ ๋ง๋ค ์ ์๋ค. java.lang.annotation.ElementType์ ์ด์ฉํ์ฌ ํน์ ํ์ ์๋ง ์ ์ฉ๋๋๋ก ์ค์ ํ๋ค.
@Target( ํ์
์ง์ ) @Retention( ์ด๋
ธํ
์ด์
์๋ช
์ฃผ๊ธฐ ) public @interface SuppressWarnings{ String[] value(); ... }
@Target
์ด๋ ธํ ์ด์ ์ ์ ์ฉ๋์์ ์ง์ ํ๋ค.

// ํด๋์ค(type), ํ๋(filed), ๋ฉ์๋(method)์ ์ ์ฉ๊ฐ๋ฅํ ์ด๋
ธํ
์ด์
. @Target( {TYPE, FILED, METHOD } ) public @interface MyAnnotation{...} // ์ฐธ๊ณ ๋ก TYPE, FILED ๋ฑ์ java.lang.annotation.ElementType ์ ์กด์ฌํ๋ ์ค์ ๊ฐ์ด๋ค. @Target( {ElementType.TYPE, ElementType.METHOD } ) public @interface MyAnnotation{...}
@Retention
์ด๋ ธํ ์ด์ ์ด ์ ์ง(retention)๋๋ ์๊ธฐ, ์ฆ ์ด๋ ธํ ์ด์ ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ง์ ํด์ค ์ ์๋ค. CLASS๋ก ์ง์ ํ๋ฉด ๋ฐํ์์์ ์กด์ฌํ๋ ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋ฐ (๋ฆฌํ๋ ์ ๋ถ๊ฐ๋ฅ, JVM์ ClassLoader ๊น์ง๋ง ์ฌ์ฉ๊ฐ๋ฅ) CLASS ๋ฅผ ์ฐ๋ ์ผ์ ๊ฑฐ์ ์๊ณ ๋ณดํต SOURCE/RUNTIME ๋ก ๊ตฌ๋ถ์ง์ด ์ฌ์ฉํ๋ค.
SOURCE | ์์ค ์ฝ๋๋ฅผ ๋ถ์ํ ๋๋ง ์๋ฏธ์๊ณ , ์ปดํ์ผ ์ดํ ๋ฐ์ดํธ ์ฝ๋์๋ ๋จ์ง ์๋๋ค. |
CLASS (๊ธฐ๋ณธ๊ฐ) | ๋ฐ์ดํธ ์ฝ๋ ํ์ผ๊น์ง ์กด์ฌ๋ ํ๋, ๋ฆฌํ๋ ์ ์ ์ด์ฉํด์ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ป์ ์๋ ์๋ค. (๋ณดํต ์ ์์ด๋ค.) |
RUNTIME | ๋ฐ์ดํธ ์ฝ๋ ํ์ผ๊น์ง ์กด์ฌํ๊ณ ๋ฆฌํ๋ ์ ์ ์ด์ฉํ์ฌ ๋ฐํ์ ์์ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค. |

@Target(ElementType.METHOD ) @Retention(RetentionPolicy.SOURCE) // ์ปดํ์ผ ์ดํ์๋ ์์ด์ง. public @interface Override{...} //์ฐธ๊ณ ๋ก ์ด๋
ธํ
์ด์
์ ์ธ ์์๋ ๋ณ ์๊ด ์๋ค. @Documented @Retention(RetentionPolicy.RUNTIME) // ์คํ ํ์๋ ์ฌ์ฉ๊ฐ๋ฅ(๋ฆฌํ๋ ์
) @Target( TYPE ) public @interface FunctionalInterface{...}
@Documented
javadoc์ผ๋ก ์์ฑํ ๋ฌธ์(html)์ ํฌํจ์ํค๋ ค๋ฉด @Documented๋ฅผ ์ฌ์ฉํ๋ค. ์ฐ๋ฆฌ๊ฐ ์ง์ ์ฌ์ฉํ ์ผ์ ๊ฑฐ์ ์๋ค.
//์ฐธ๊ณ ๋ก ์ด๋
ธํ
์ด์
์ ์ธ ์์๋ ๋ณ ์๊ด ์๋ค. @Documented @Retention(RetentionPolicy.RUNTIME) // ์คํ ํ์๋ ์ฌ์ฉ๊ฐ๋ฅ(๋ฆฌํ๋ ์
) @Target( TYPE ) public @interface FunctionalInterface{...}
@Inherited (์์)
ํด๋น ์ด๋ ธํ ์ด์ ์ ๋์์ ์์๊น์ง ์ ์ฉ๋๊ฒ ํ ๋ ์ฌ์ฉํ๋ค. ๊ฑฐ์ ์ฌ์ฉํ ์ผ์ด ์๋ ์ด๋ ธํ ์ด์ ์ด๊ธด ํ๋ค.
@Inheriteed @interface MyAnno @MyAnno class Parent{} // ์ด๋
ธํ
์ด์
์ ์ฉ๋จ class Child extends Parent{} // ์ด๋
ธํ
์ด์
์ ์ฉ๋จ.
@Repeatable
๊ฐ์ ์ด๋ ธํ ์ด์ ์ ์ฌ๋ฌ๊ฐ ๋ถ์ผ ์ ์๋๋ก ๋ง๋ค์ด์ค๋ค. ์ด๊ฒ๋ ๊ฑฐ์ ์ฌ์ฉํ ์ผ์ ์๋ค.
@Repeatable(ToDos.class) @interface ToDo{ ... } // ๋จ, ์ ๋๋ก ์ฌ์ฉํ๊ธฐ ์ํด์๋ ํ๋๋ก ๋ฌถ์ด์ ๊ด๋ฆฌํ ์ปจํ
์ด๋ ์ด๋
ธํ
์ด์
์ ๊ฐ์ด ์ ์ํด์ผํ๋ค. @interface ToDos{ ToDo[] value();// ์ด๋
ธํ
์ด์
์ ๋ฐฐ์ดํ์
์ผ๋ก ์ ์ธ. ์ฐธ๊ณ ๋ก ์ด๋ฆ์ ๋ฐ๋์ value์ฌ์ผํจ. // ์ด๋
ธํ
์ด์
์์์ ์ด๋ฆ์ด value์ธ ๊ฒฝ์ฐ์๋ ์๋ตํ์ฌ ์
๋ ฅ ๊ฐ๋ฅ. }
@ToDo("delete test codes.") @ToDo("override inheriteed methods") class MyClass{ ... }
# ์ด๋ ธํ ์ด์ ํ์ ์ ์ํ๊ธฐ
์ด๋ ธํ ์ด์ ๋ ํด๋์ค์ ๋์ผํ๊ฒ ์ ์ ํ ์ ์๋ค. ๋จ ํ์ ์ ์ ์ํ ๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์ถ์๋ฉ์๋๋ง ์ด์ฉํ ์ ์๋ค. ๋น์ฐํ ์ถ์๋ฉ์๋๋ก๋ง ์ด๋ฃจ์ด์ ธ์์ผ๋ฏ๋ก, ์์ธ๋ฅผ ์ ์ธํ๋๊ฑฐ๋ ์ ๋ค๋ฆญ<T>๋ฅผ ์ฌ์ฉํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋ค.
@interface ์ด๋
ธํ
์ด์
์ด๋ฆ{ ํ์
์์์ด๋ฆ(); // ์ถ์๋ฉ์๋๋ง ์ฌ์ฉํ ์ ์๋ค. } @interface TestInfo{ int count(); static final id =100; // ์์ธ์ ์ผ๋ก ์์๋ ์ฌ์ฉ๊ฐ๋ฅํ๋ค. ์๋ตํด๋ ์์๋ก ์ทจ๊ธํจ. String testedBy(); String[] testTools(); // ๋ฐฐ์ด TestType testType(); // enum ์ด๋ Class๋ ๊ฐ๋ฅํ๋ค. DateTime testDate(); // ์์ ์ด ์๋ ๋ค๋ฅธ ์ด๋
ธํ
์ด์
(@DataTime)์ ํฌํจํ ์ ์๋ค. }
์ด๋ ๊ฒ ์ ์ํ ์ด๋ ธํ ์ด์ ์ ์๋์ ๊ฐ์ด ์ฌ์ฉํ ์์๋ค. ์ด๋ ๊ฒ ๋ฐ์ ์ ๋ณด๋ฅผ ์ปดํ์ผ๋ฌ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ ํด์ด ์ฌ์ฉํ ์ ์๋ค. ๋ณดํต์ ์ด๋ ธํ ์ด์ ์ ์ ์ฅ๋ ๊ฐ์ ๋ค๋ฃจ๋ ์ผ์ ๊ฑฐ์ ์๊ณ ๋ณดํต ๋ง๋ค์ด์ง ์ด๋ ธํ ์ด์ ์ ์๋์ ๊ฐ์ด ์ฌ์ฉํ๊ฒ ๋๋ค.

@ default ๊ฐ
์ ์ฉ์ ๊ฐ์ ์ง์ ํ์ง ์์์ ๋ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ ์ ์๋ค. ๋น์ฐํ๊ฑฐ์ง๋ง default ๋ฉ์๋๋ ์ฌ์ฉ ๋ถ๊ฐ๋ฅํ๋ค.
@interface TestInfo{ int count() default 1 // ๊ธฐ๋ณธ๊ฐ 1 // ๋น์ฐํ๊ฑฐ์ง๋ง ๊ธฐ๋ณธ๊ฐ์ผ๋ก null์ ์ค ์๋ ์๋ค. int id = 100; // ์ด๋ static final int id=100์ผ๋ก ๋ณํ๋๋ค. ์ฆ ์์์ด๋ค. }
@ value ์์
์์์ ์ด๋ฆ์ด value์ผ๋๋ ์ฌ์ฉ์ ์ด๋ฆ์ ์๋ตํ ์ ์๋ค.
@interface TestInfo{ String value(); } @TestInfo("์ด๋ ๊ฒ ๋ฐ๋ก ์ฌ์ฉํ ์์์") // value="~"๋ก ์ทจ๊ธ๋จ. class NewClass {...}
@ ์์ ํ์ ์ด ๋ฐฐ์ด์ผ ๋
๊ดํธ { } ๋ฅผ ์ฌ์ฉํด์ ์ ๋ ฅํ๋ฉฐ, ๊ฐ์ด ํ๋ ์ธ๊ฒฝ์ฐ ๊ดํธ๋ฅผ์๋ตํด๋ ๋๋ค.
@Test(testTools= {"JUnit", "AutoTester"} )// ๋ฐฐ์ด ํ์
@Test(testTools ="JUnit")// ๊ฐ์ด ํ๋์ผ ๋ ์๋ต๊ฐ๋ฅ @Test(testTools = {})// ์ค ๊ฐ์ด ์์๋ ๋น๊ดํธ๋ฅผ ์ค์ผํจ. testTools; ์ด๋ฐ๊ฑฐ ์๋จ.
@ ์ด๋ ธํ ์ด์ ์ ๊ธฐ๋ณธ ์ถ์๋ฉ์๋
java.lang.annotation.Annotation ์ ๋ชจ๋ ์ด๋ ธํ ์ด์ ์ ์กฐ์ ์ธํฐํ์ด์ค์ด๋ค. ํ์ง๋ง extends๋ก ์์์ ํ ์๋ ์๋ค.(ํ๋ฉด ์ปดํ์ผ ์๋ฌ) ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์ด๋ ๊ฒ ๋ง๋ ์ด์ ๋, Object์ ๋ฉ์๋์ฒ๋ผ ๋ชจ๋ ์ด๋ ธํ ์ด์ ์ด ๊ฐ์ง๊ณ ์๋ ์ถ์๋ฉ์๋๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด์์ด๋ค.
package java.lnag.annotation; public interface Annotation{ boolean equals(Object obj); int hashCode(); String toString(); Class<? extends Annotation> annotationType(); // ์ด๋
ธํ
์ด์
ํ์
๋ฐํ }
@ Marker ์ด๋ ธํ ์ด์
๊ฑฐ์ฐฝํ๊ฑด ์๋๊ณ , ์์์์ด ๋น์ด์๋ ์ด๋ ธํ ์ด์ ์ ์๋ฏธํ๋ค. ์ด๋ฆ ๊ทธ๋๋ก ํน์ ํ๋, ๋ฉ์๋๋ฅผ ๊ตฌ๋ถํ ๋ง์ปค๋ก ์ฐ์ธ๋ค.
@Target(METHOD) @Retention(SOURCE) public @interface Test{} // ๋ง์ปค ์ด๋
ธํ
์ด์
@Test // ํ
์คํธ ํ์์ฉ๋. public void method(){...} @Deprecated // ์ฌ์ฉํ๋ฉด ๊ฒฝ๊ณ ๋์ฐ๋ ์ฉ๋. public int getDate(){...}
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev