item 65 sijun - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

[μ•„μ΄ν…œ65] λ¦¬ν”Œλ ‰μ…˜λ³΄λ‹€λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λΌ

λ¦¬ν”Œλ ‰μ…˜(java.lang.reflect)λ₯Ό μ΄μš©ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ—μ„œ μž„μ˜μ˜ ν΄λž˜μŠ€μ— μ ‘κ·Όν•  수 μžˆλ‹€. Class 객체가 주어지면 κ·Έ 클래슀의 μƒμ„±μž, λ©”μ„œλ“œ, ν•„λ“œμ— ν•΄λ‹Ήν•˜λŠ” Consturctor, Method, Field μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ Έμ˜¬ 수 있고, μ΄μ–΄μ„œ 이 μΈμŠ€ν„΄μŠ€λ“€λ‘œλŠ” κ·Έ 클래슀의 멀버 이름, ν•„λ“œ νƒ€μž…, λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜ 등을 κ°€μ Έμ˜¬ 수 μžˆλ‹€. λ‚˜μ•„κ°€ Consturctor, Method, Field μΈμŠ€ν„΄μŠ€λ₯Ό μ΄μš©ν•΄ 각각에 μ—°κ²°λœ μ‹€μ œ μƒμ„±μž, λ©”μ„œλ“œ, ν•„λ“œλ₯Ό μ‘°μž‘ν•  μˆ˜λ„ μžˆλ‹€.

public class Test{
	
	public static void main(String[] args) throws Exception {
		
		SampleClass sampleClass = new SampleClass();
		Class<SampleClass> cs = SampleClass.class;
		
		Field[] fields = cs.getDeclaredFields(); // field λͺ©λ‘ λ°›κΈ°
		Method[] methods = cs.getDeclaredMethods(); // method λͺ©λ‘ λ°›κΈ°
		cs.getConstructors(); // constructor 호좜
		
		for(Field field : fields) {
			System.out.println(field.getName());
		}
		
		for(Method method : methods) {
			method.invoke(sampleClass,(Object[]) null);
		}
	}
}

class SampleClass{
	public int testNum;
	public int testNum2;
	
	public SampleClass() {
		System.out.println("constructor이 μ‹€ν–‰λ˜μ—ˆλ‹€");
	}
	public void testMethod() {
		System.out.println("testMethod이 μ‹€ν–‰λ˜μ—ˆλ‹€");
	}
}

----------------------------
constructor이 μ‹€ν–‰λ˜μ—ˆλ‹€
testNum
testNum2
testMethod이 μ‹€ν–‰λ˜μ—ˆλ‹€

λ¦¬ν”Œλ ‰μ…˜μ„ μ΄μš©ν•˜λ©΄ 컴파일 λ‹Ήμ‹œμ— μ‘΄μž¬ν•˜μ§€ μ•Šλ˜ ν΄λž˜μŠ€λ„ μ΄μš©ν•  수 μžˆλŠ”λ°, 단점도 μžˆλ‹€.

  1. μ»΄νŒŒμΌνƒ€μž„ νƒ€μž… 검사가 μ£ΌλŠ” 이점을 ν•˜λ‚˜λ„ λˆ„λ¦΄ 수 μ—†λ‹€.

    μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” ν˜Ήμ€ μ ‘κ·Όν•  수 μ—†λŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ € μ‹œλ„ν•˜λ©΄ λŸ°νƒ€μž„ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

  2. λ¦¬ν”Œλ ‰μ…˜μ„ μ΄μš©ν•˜λ©΄ μ½”λ“œκ°€ μ§€μ €λΆ„ν•˜κ³  μž₯황해진닀.

  3. μ„±λŠ₯이 떨어진닀

μ½”λ“œ 뢄석 λ„κ΅¬λ‚˜ μ˜μ‘΄κ΄€κ³„ μ£Όμž… ν”„λ ˆμž„μ›Œν¬μ²˜λŸΌ λ¦¬ν”Œλ ‰μ…˜μ„ 써야 ν•˜λŠ” λ³΅μž‘ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λͺ‡ 가지 μžˆλ‹€. ν•˜μ§€λ§Œ 이런 λ„κ΅¬λ“€λ§ˆμ € λ¦¬ν”Œλ ‰μ…˜ μ‚¬μš©μ„ 점차 쀄이고 μžˆλ‹€. 단점이 λͺ…λ°±ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

λ¦¬ν”Œλ ‰μ…˜μ€ μ•„μ£Ό μ œν•œλœ ν˜•νƒœλ‘œλ§Œ μ‚¬μš©ν•΄μ•Ό κ·Έ 단점을 ν”Όν•˜κ³  이점만 μ·¨ν•  수 μžˆλ‹€.

package effectivejava.chapter9.item65;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Set;

// λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ ν™œμš©ν•œ μΈμŠ€ν„΄μŠ€ν™” 데λͺ¨
public class ReflectiveInstantiation {
    // μ½”λ“œ 65-1 λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ μƒμ„±ν•˜κ³  μΈν„°νŽ˜μ΄μŠ€λ‘œ μ°Έμ‘°ν•΄ ν™œμš©ν•œλ‹€. (372-373μͺ½)
    public static void main(String[] args) {
        // 클래슀 이름을 Class 객체둜 λ³€ν™˜
        Class<? extends Set<String>> cl = null;
        try {
            cl = (Class<? extends Set<String>>)  // 비검사 ν˜•λ³€ν™˜!
                    Class.forName(args[0]);
        } catch (ClassNotFoundException e) {
            fatalError("클래슀λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.");
        }

        // μƒμ„±μžλ₯Ό μ–»λŠ”λ‹€.
        Constructor<? extends Set<String>> cons = null;
        try {
            cons = cl.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
            fatalError("λ§€κ°œλ³€μˆ˜ μ—†λŠ” μƒμ„±μžλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.");
        }

        // μ§‘ν•©μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“ λ‹€.
        Set<String> s = null;
        try {
            s = cons.newInstance();
        } catch (IllegalAccessException e) {
            fatalError("μƒμ„±μžμ— μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.");
        } catch (InstantiationException e) {
            fatalError("클래슀λ₯Ό μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†μŠ΅λ‹ˆλ‹€.");
        } catch (InvocationTargetException e) {
            fatalError("μƒμ„±μžκ°€ μ˜ˆμ™Έλ₯Ό λ˜μ‘ŒμŠ΅λ‹ˆλ‹€: " + e.getCause());
        } catch (ClassCastException e) {
            fatalError("Set을 κ΅¬ν˜„ν•˜μ§€ μ•Šμ€ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.");
        }

        // μƒμ„±ν•œ 집합을 μ‚¬μš©ν•œλ‹€.
        s.addAll(Arrays.asList(args).subList(1, args.length));
        System.out.println(s);
    }

    private static void fatalError(String msg) {
        System.err.println(msg);
        System.exit(1);
    }
}

μœ„ μ½”λ“œλŠ” 두 가지 단점을 보여쀀닀.

  1. λŸ°νƒ€μž„μ— 총 μ—¬μ„―κ°€μ§€λ‚˜ λ˜λŠ” μ˜ˆμ™Έλ₯Ό 던질 수 μžˆλ‹€.
  2. 클래슀 μ΄λ¦„λ§ŒμœΌλ‘œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성해내기 μœ„ν•΄ 무렀 25μ€„μ΄λ‚˜ λ˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€.

객체가 일단 λ§Œλ“€μ–΄μ§€λ©΄ κ·Έ ν›„μ˜ μ½”λ“œλŠ” μ—¬νƒ€μ˜ Set μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•  λ•Œμ™€ λ˜‘κ°™λ‹€.

λ¦¬ν”Œλ ‰μ…˜μ€ λŸ°νƒ€μž„μ— μ‘΄μž¬ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλŠ” λ‹€λ₯Έ 클래슀, λ©”μ„œλ“œ, ν•„λ“œμ™€μ˜ μ˜μ‘΄μ„±μ„ 관리할 λ•Œ μ ν•©ν•˜λ‹€.

이 기법은 버전이 μ—¬λŸ¬ 개 μ‘΄μž¬ν•˜λŠ” μ™ΈλΆ€ νŒ¨ν‚€μ§€λ₯Ό λ‹€λ£° λ•Œ μœ μš©ν•˜λ‹€. 가동할 수 μžˆλŠ” μ΅œμ†Œν•œμ˜ ν™˜κ²½, 즉 주둜 κ°€μž₯ 였래된 λ²„μ „λ§Œμ„ μ§€μ›ν•˜λ„λ‘ μ»΄νŒŒμΌν•œ ν›„, 이후 λ²„μ „μ˜ ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œ 등은 λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ μ ‘κ·Όν•˜λŠ” 방식이닀.

μ΄λ ‡κ²Œ ν•˜λ €λ©΄ μ ‘κ·Όν•˜λ €λŠ” μƒˆλ‘œμš΄ ν΄λž˜μŠ€λ‚˜ λ©”μ„œλ“œκ°€ λŸ°νƒ€μž„μ— μ‘΄μž¬ν•˜μ§€ μ•Šμ„ 수 μžˆλ‹€λŠ” 사싀을 λ°˜λ“œμ‹œ κ°μ•ˆν•΄μ•Όν•˜λ©°, λŒ€μ²΄ μˆ˜λ‹¨μ΄λ‚˜ κΈ°λŠ₯을 λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

핡심정리

λ¦¬ν”Œλ ‰μ…˜μ€ λ³΅μž‘ν•œ 특수 μ‹œμŠ€ν…œμ„ κ°œλ°œν•  λ•Œ ν•„μš”ν•œ κ°•λ ₯ν•œ κΈ°λŠ₯μ΄μ§€λ§Œ, 단점도 λ§Žλ‹€. μ»΄νŒŒμΌνƒ€μž„μ—λŠ” μ•Œ 수 μ—†λŠ” 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•œλ‹€λ©΄ λ¦¬ν”Œλ ‰μ…˜μ„ μ‚¬μš©ν•΄μ•Ό ν•  것이닀. 단, λ˜λ„λ‘ 객체 μƒμ„±μ—λ§Œ μ‚¬μš©ν•˜κ³ , μƒμ„±ν•œ 객체λ₯Ό μ΄μš©ν•  λ•ŒλŠ” μ μ ˆν•œ μΈν„°νŽ˜μ΄μŠ€λ‚˜ μ»΄νŒŒμΌνƒ€μž„μ— μ•Œ 수 μžˆλŠ” μƒμœ„ 클래슀둜 ν˜•λ³€ν™˜ν•΄ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

⚠️ **GitHub.com Fallback** ⚠️