[Java] Reflection ์˜ˆ์ œ

์ž๋ฐ”์—์„œ ๋ฆฌํ”Œ๋ž™์…˜์€ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์œผ๋กœ, ๋‚ด๋ถ€ properties๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ •๋ณด๋ฅผ ์ง์ ‘ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋Š” manual์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ํด๋ž˜์Šค ์ •๋ณด, ํ˜น์€ ๋ฉ”์„œ๋“œ ์ •๋ณด๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. ํด๋ž˜์Šค ์ •๋ณด ๊ฐ€์ ธ์˜ค๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•

public static void main(String[] args){

  // ์ธ์Šคํ„ด์Šค์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ
  Member member = new Member();
  Class<? extends Member> m1Class = member.getClass();

  // ํƒ€์ž…์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•
  Class<Member> m2Class = Member.class;

  // full package name
  Class<?> m3Class = Class.forName("com.example.demo.member");
}

์ž๋ฐ”์˜ Class๋ผ๋Š” API๋ฅผ ํ†ตํ•ด์„œ ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ํ†ตํ•ด์„œ ํ•„๋“œ, ๋ฉ”์„œ๋“œ, ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ๋‚˜, ๋ฉ”์„œ๋“œ, ํ•„๋“œ์— ์ ‘๊ทผํ•  ๋•Œ๋Š” ์ ‘๊ทผ์ œํ•œ์ž๊ฐ€ private์ธ ๊ฒฝ์šฐ์—๋Š” getDeclaredxxx() ์‹œ๋ฆฌ์ฆˆ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ „๋ถ€๋‹ค ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ๊ฐ๊ฐ์˜ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ setAccesible(true) ๊ฐ’์„ ์ฃผ๋ฉด ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด ์ง„๋‹ค.

2.์ž๋ฐ” @์• ๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉํ•˜๊ธฐ

public @interface CustomAnnotation {

}

// ์‚ฌ์šฉํ• ๋•Œ
@CustomAnnotation
public class Member {

  ..//์ƒ๋žต
}

@interface ํƒ€์ž…์œผ๋กœ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ CustomAnnotation ์€ ์•„๋ฌด ๊ธฐ๋Šฅ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ์ € ์ฃผ์„์˜ ์—ญํ• ์ผ ๋ฟ, javaํŒŒ์ผ์ด compile์ด ๋˜๊ณ  classํŒŒ์ผ๊นŒ์ง€ ๊ฐ”์„๋•Œ, ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ๋‚จ์•„์žˆ๊ธด ํ•˜์ง€๋งŒ, ๋ฐ”์ดํŠธ์ฝ”๋“œ๊ฐ€ JVM์—์„œ ๋กœ๋”ฉ์ด ๋˜์–ด ๋™์ž‘ํ• ๋•Œ ๊นŒ์ง€ ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค. ์• ๋…ธํ…Œ์ด์…˜์˜ ๊ธฐ๋ณธ์ด @Retention(RetentionPolicy.CLASS) ์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์ŠคํŒŒ์ผ ๊นŒ์ง€๋งŒ ์œ ์ง€(Retaion)๋œ๋‹ค. @Retention(RetentionPolicy.RUNTIME) ์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๊ทธ์ œ์„œ์•ผ, ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation{

}

@MyAnnotaion
public class Member{

}
public static void main(String[] args){
  Class<Member> memberClass = Member.class;
  Arrays.stream(memberClass.getAnnotations()).forEach(System.out::println);
}

์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค์—์„œ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

3.๊ฐ์ฒด ์ง์ ‘ ๋งŒ๋“ค๊ธฐ

class์—์„œ getConstructor() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง€๊ณ ์™€์„œ, constructor.newInstance() ๋ฅผ ํ†ตํ•ด์„œ ๋งŒ๋“ ๋‹ค.

์ถ”๊ฐ€ ํ•™์Šต

์—ฐ๊ด€ ํฌ์ŠคํŠธ