Skip to content

Latest commit

Β 

History

History
81 lines (76 loc) Β· 5.28 KB

File metadata and controls

81 lines (76 loc) Β· 5.28 KB

Reflection

Reflection μ΄λž€?

  • Reflection은 μ‹€ν–‰ 쀑인 Java ν”„λ‘œκ·Έλž¨μ—μ„œ 클래슀, μΈν„°νŽ˜μ΄μŠ€, ν•„λ“œ, λ©”μ„œλ“œ λ“±μ˜ 정보λ₯Ό κ°€μ Έμ˜€κ³ , 이런 μš”μ†Œλ“€μ„ λ™μ μœΌλ‘œ μ‘°μž‘ν•  수 μžˆλŠ” κΈ°λŠ₯이닀.
  • Reflection을 μ‚¬μš©ν•˜λ©΄ 컴파일 μ‹œμ μ— μ•Œ 수 μ—†μ—ˆλ˜ 클래슀의 정보λ₯Ό μ‘°μ‚¬ν•˜κ³ , 객체λ₯Ό μƒμ„±ν•˜λ©°, λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³ , ν•„λ“œμ— μ ‘κ·Όν•  수 μžˆλ‹€.

Reflection μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 경우

  1. 클래슀의 정보 뢄석
    • Reflection을 μ‚¬μš©ν•˜μ—¬ μ‹€ν–‰ 쀑인 Java ν”„λ‘œκ·Έλž¨μ—μ„œ 클래슀의 이름, 상속 계측, κ΅¬ν˜„ μΈν„°νŽ˜μ΄μŠ€, ν•„λ“œ 및 λ©”μ„œλ“œ λ“±μ˜ 정보λ₯Ό λ™μ μœΌλ‘œ μ•Œμ•„λ‚Ό 수 μžˆλ‹€.
    • 이λ₯Ό ν™œμš©ν•΄ 클래슀의 동적 λ‘œλ”©, 메타데이터 검사, 동적 바인딩 λ“± μ—¬λŸ¬ μž‘μ—…μ΄ μˆ˜ν–‰ κ°€λŠ₯ν•˜λ‹€.
  2. 객체의 동적 생성
    • Reflection을 μ‚¬μš©ν•˜λ©΄ μ‹€ν–‰ 쀑에 λ™μ μœΌλ‘œ 객체λ₯Ό 생성할 수 μžˆλ‹€.
    • 클래슀 이름을 λ™μ μœΌλ‘œ μ•Œμ•„λ‚΄κ³ , Class.newInstance() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό 생성할 수 μžˆλ‹€.
    • νŒ©ν† λ¦¬ νŒ¨ν„΄, μ˜μ‘΄μ„± μ£Όμž… λ“±μ˜ μƒν™©μ—μ„œ μœ μš©ν•  수 μžˆλ‹€.
  3. λ©”μ„œλ“œμ˜ 동적 호좜
    • Reflection을 μ‚¬μš©ν•˜λ©΄ μ‹€ν–‰ 쀑에 λ©”μ„œλ“œλ₯Ό λ™μ μœΌλ‘œ ν˜ΈμΆœν•  수 μžˆλ‹€.
    • λ©”μ„œλ“œ 이름, λ§€κ°œλ³€μˆ˜ νƒ€μž… λ“±μ˜ 정보λ₯Ό μ•Œμ•„λ‚΄κ³ , Method.invoke() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.
    • Reflection 기반의 동적 λ””μŠ€νŒ¨μΉ˜ λ“±μ˜ μƒν™©μ—μ„œ μœ μš©ν•  수 μžˆλ‹€.

Reflection의 λ‚΄μž₯ν•¨μˆ˜

  • μ•„λž˜ ν•¨μˆ˜λ“€μ€ java.lang.Class 클래슀의 λ©”μ„œλ“œλ‘œ μ œκ³΅ν•œλ‹€.
  1. getDeclaredFields()
    • 클래슀의 λͺ¨λ“  ν•„λ“œλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • 상속받은 ν•„λ“œλ‚˜ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 상속받은 ν•„λ“œλŠ” ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • Field λ°°μ—΄λ‘œ λ°˜ν™˜λ˜λ©°, 각 ν•„λ“œμ—λŠ” ν•΄λ‹Ή ν•„λ“œμ˜ 정보와 κΈ°λŠ₯에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œκ°€ μžˆλ‹€.
  2. getDeclaredMethods()
    • 클래슀의 λͺ¨λ“  λ©”μ„œλ“œλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • 상속받은 λ©”μ„œλ“œλ‚˜ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 상속받은 λ©”μ„œλ“œλŠ” ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • Method λ°°μ—΄λ‘œ λ°˜ν™˜λ˜λ©°, 각 λ©”μ„œλ“œμ—λŠ” ν•΄λ‹Ή λ©”μ„œλ“œμ˜ 정보와 κΈ°λŠ₯에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œκ°€ μžˆλ‹€.
  3. getDeclaredConstructors()
    • 클래슀의 λͺ¨λ“  μƒμ„±μžλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • Constructor λ°°μ—΄λ‘œ λ°˜ν™˜λ˜λ©°, 각 μƒμ„±μžμ—λŠ” ν•΄λ‹Ή μƒμ„±μžμ˜ 정보와 κΈ°λŠ₯에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œκ°€ μžˆλ‹€.
  4. getMethod(String name, Class<?>... parameterType)
    • μ§€μ •λœ 이름과 λ§€κ°œλ³€μˆ˜ νƒ€μž…μ— ν•΄λ‹Ήν•˜λŠ” 곡개 λ©”μ„œλ“œλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • 상속받은 λ©”μ„œλ“œ λ˜ν•œ ν¬ν•¨ν•œλ‹€.
    • Method 객체λ₯Ό λ°˜ν™˜ν•˜λ©°, ν•΄λ‹Ή λ©”μ„œλ“œμ—λŠ” ν•΄λ‹Ή λ©”μ„œλ“œμ˜ 정보와 κΈ°λŠ₯에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œκ°€ μžˆλ‹€.
  5. getField(String name)
    • μ§€μ •λœ μ΄λ¦„μ˜ 곡개 ν•„λ“œλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • 상속받은 ν•„λ“œ λ˜ν•œ ν¬ν•¨ν•œλ‹€.
    • Field 객체λ₯Ό λ°˜ν™˜ν•˜λ©°, ν•΄λ‹Ή ν•„λ“œμ—λŠ” ν•΄λ‹Ή ν•„λ“œμ˜ 정보와 κΈ°λŠ₯에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œκ°€ μžˆλ‹€.
  • 이 외에도 getSuperclass(), getInterface(), newInstance() λ“±μ˜ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ 클래슀의 μƒμœ„ 클래슀, κ΅¬ν˜„ν•œ μΈν„°νŽ˜μ΄μŠ€, 객체의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” λ“±μ˜ λ™μž‘μ„ μˆ˜ν–‰ν•  수 μžˆλ‹€.

Reflection 주의 사항

  1. μ„±λŠ₯
    • Reflection은 일반적인 λ©”μ„œλ“œ ν˜ΈμΆœλ³΄λ‹€ μ„±λŠ₯이 λ–¨μ–΄μ§ˆ 수 μžˆλ‹€.
    • Reflection μž‘μ—…μ€ 좔가적인 μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•˜λ―€λ‘œ μ„±λŠ₯이 μ€‘μš”ν•œ μ½”λ“œμ—μ„œ λ„ˆλ¬΄ 자주 μ‚¬μš©ν•˜λŠ” 것은 μ’‹μ§€ μ•Šλ‹€.
  2. λ³΄μ•ˆ
    • Reflection을 μ‚¬μš©ν•˜λ©΄ μ ‘κ·Ό μ œν•œμžλ₯Ό μš°νšŒν•˜μ—¬ private 멀버에 μ ‘κ·Όν•  수 μžˆλ‹€.
    • Reflection을 μ‚¬μš©ν•  λ•ŒλŠ” λ³΄μ•ˆ 검사λ₯Ό μΆ©λΆ„νžˆ μˆ˜ν–‰ν•˜κ³  ν•„μš”ν•œ κΆŒν•œμ„ 확인해야 ν•œλ‹€.
  3. 가독성 및 μœ μ§€λ³΄μˆ˜μ„±
    • Reflection은 μ½”λ“œμ˜ 가독성과 μœ μ§€λ³΄μˆ˜μ„±μ„ μ €ν•˜μ‹œν‚¬ 수 μžˆλ‹€.
    • Reflection을 μ‚¬μš©ν•˜λ©΄ μ½”λ“œμ˜ λ™μž‘μ΄ 동적이 λ˜λ―€λ‘œ μ½”λ“œλ₯Ό μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§ˆ 수 μžˆλ‹€.
    • Reflection을 μ‚¬μš©ν•  λ•ŒλŠ” λͺ…ν™•ν•œ μ΄μœ μ™€ λͺ©μ μ΄ μžˆμ„ κ²½μš°μ—λ§Œ μ‚¬μš©ν•˜κ³ , μ£Όμ„μ΄λ‚˜ λ¬Έμ„œν™”λ₯Ό 톡해 μ½”λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•νžˆ 전달해야 ν•œλ‹€.

예제 μ†ŒμŠ€

public class ReflectionExample {
	public static void main(String[] args) throws Exception {
       MyClass instance = new MyClass();
		
		// 클래슀 정보 κ°€μ Έμ˜€κΈ°
       Class<?> clazz = MyClass.class;
	   
	   // ν•„λ“œμ— μ ‘κ·Όν•˜μ—¬ κ°’ μ„€μ •ν•˜κΈ°
       Field field = clazz.getDeclaredField("myField");
	   field.setAccessible(true);   // μ ‘κ·Ό κΆŒν•œ μ„€μ •
	   field.set(instance, "New Value");
	   
	   // λ©”μ„œλ“œ ν˜ΈμΆœν•˜κΈ°
       Method method = clazz.getDeclaredMethod("myMethod");
	   method.setAccessible(true);
	   method.invoke(instance);
    }
}

class MyClass {
	private String myField;
	
	private void myMethod() {
       System.out.println("My Method.");
    }
}
  • MyClass 클래슀의 ν•„λ“œ(myField)와 λ©”μ„œλ“œ(myMethod)에 μ ‘κ·Όν•˜μ—¬ 값을 μ„€μ •ν•˜κ³  λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
  • Class 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ 클래슀 정보λ₯Ό κ°€μ Έμ˜€κ³ , Field와 Method 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•„λ“œμ™€ λ©”μ„œλ“œμ— μ ‘κ·Όν•œλ‹€.
  • setAccessible(true)둜 μ ‘κ·Ό κΆŒν•œμ„ μ„€μ •ν•΄μ•Ό private 멀버에 μ ‘κ·Ό κ°€λŠ₯ν•˜λ‹€.