item 52 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

λ‹€μ€‘μ •μ˜λŠ” μ‹ μ€‘νžˆ μ‚¬μš©ν•˜λΌ

  • λ‹€μŒμ€ μ»¬λ ‰μ…˜μ„ 집합, 리슀트, κ·Έ μ™Έλ‘œ κ΅¬λΆ„ν•˜κ³ μž λ§Œλ“  ν”„λ‘œκ·Έλž¨μ΄λ‹€.
// μ½”λ“œ 52-1 μ»¬λ ‰μ…˜ λΆ„λ₯˜κΈ° - 였λ₯˜! 이 ν”„λ‘œκ·Έλž¨μ€ 무엇을 좜λ ₯ν• κΉŒ? (312μͺ½)
public class CollectionClassifier {
    public static String classify(Set<?> s) {
        return "집합";
    }

    public static String classify(List<?> lst) {
        return "리슀트";
    }

    public static String classify(Collection<?> c) {
        return "κ·Έ μ™Έ";
    }

    public static void main(String[] args) {
        Collection<?>[] collections = {
                new HashSet<String>(),
                new ArrayList<BigInteger>(),
                new HashMap<String, String>().values()
        };

        for (Collection<?> c : collections)
            System.out.println(classify(c));
    }
}
  • μ‹€μ œλ‘œ 싀행해보면 "κ·Έ μ™Έ"만 μ„Έλ²ˆ 연달아 좜λ ₯ν•œλ‹€.
  • λ‹€μ€‘μ •μ˜ (overloading, μ˜€λ²„λ‘œλ”©)된 μ„Έ classify 쀑 μ–΄λŠ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€κ°€ 컴파일 νƒ€μž„μ— 정해지기 λ•Œλ¬Έμ΄λ‹€.
  • 컴파일 νƒ€μž„μ—λŠ” forλ¬Έ μ•ˆμ˜ cλŠ” 항상 Collection<?> νƒ€μž…μ΄λ‹€. λŸ°νƒ€μž„μ—λŠ” 맀번 λ‹¬λΌμ§€μ§€λ§Œ, ν˜ΈμΆœν•  λ©”μ„œλ“œλ₯Ό μ„ νƒν•˜λŠ” λ°λŠ” 영ν–₯을 주지 λͺ»ν•œλ‹€.
  • 컴파일 νƒ€μž„μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…μ„ κΈ°μ€€μœΌλ‘œ 항상 μ„Έ 번째 λ©”μ„œλ“œμΈ classify(Collection<?>)만 ν˜ΈμΆœν•˜λŠ” 것이닀.

이처럼 직관과 μ–΄κΈ‹λ‚˜λŠ” μ΄μœ λŠ” μž¬μ •μ˜ν•œ λ©”μ„œλ“œλŠ” λ™μ μœΌλ‘œ μ„ νƒλ˜κ³  λ‹€μ€‘μ •μ˜ν•œ λ©”μ„œλ“œλŠ” μ •μ μœΌλ‘œ μ„ νƒλ˜κΈ° λ•Œλ¬Έμ΄λ‹€.

λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν–ˆλ‹€λ©΄ ν•΄λ‹Ή 객체의 λŸ°νƒ€μž„ νƒ€μž…μ΄ μ–΄λ–€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€μ˜ 기쀀이 λœλ‹€.

λ©”μ„œλ“œ μž¬μ •μ˜λž€ μƒμœ„ ν΄λž˜μŠ€κ°€ μ •μ˜ν•œ 것과 λ˜‘κ°™μ€ μ‹œκ·Έλ‹ˆμ²˜μ˜ λ©”μ„œλ“œλ₯Ό ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ λ‹€μ‹œ μ •μ˜ν•œ 것을 λ§ν•œλ‹€.

λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ ν•œ λ‹€μŒ 'ν•˜μœ„ 클래슀의 μΈμŠ€ν„΄μŠ€'μ—μ„œ κ·Έ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ μž¬μ •μ˜ν•œ λ©”μ„œλ“œκ°€ μ‹€ν–‰λœλ‹€. 컴파일 νƒ€μž„μ— κ·Έ μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ΄ λ¬΄μ—‡μ΄μ—ˆλƒλŠ” 상관없닀.

// μž¬μ •μ˜λœ λ©”μ„œλ“œ 호좜 λ©”μ»€λ‹ˆμ¦˜ (313μͺ½, μ½”λ“œ 52-2의 일뢀)

class Wine {
    String name() { return "포도주"; }
}

class SparklingWine extends Wine {
    @Override String name() { return "λ°œν¬μ„± 포도주"; }
}

class Champagne extends SparklingWine {
    @Override String name() { return "샴폐인"; }
}

// wine ν΄λž˜μŠ€μ— μ •μ˜λœ name λ©”μ„œλ“œλŠ” ν•˜μœ„ 클래슀인 SparklingWine, Champagneμ—μ„œ μž¬μ •μ˜λœλ‹€. 
// "포도주", "λ°œν¬μ„± 포도주", "샴폐인"을 μ°¨λ‘€λ‘œ 좜λ ₯ν•œλ‹€. 
// forλ¬Έμ—μ„œμ˜ 컴파일 νƒ€μž„ νƒ€μž…μ΄ λͺ¨λ‘ wine인 것에 λ¬΄κ΄€ν•˜κ²Œ 항상 'κ°€μž₯ ν•˜μœ„μ—μ„œ μ •μ˜ν•œ' μž¬μ •μ˜ λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜λŠ” 것이닀. 
public class Overriding {
    public static void main(String[] args) {
        List<Wine> wineList = List.of(
                new Wine(), new SparklingWine(), new Champagne());

        for (Wine wine : wineList)
            System.out.println(wine.name());
    }
} 

λ‹€μ€‘μ •μ˜λœ λ©”μ„œλ“œ μ‚¬μ΄μ—μ„œλŠ” 객체의 λŸ°νƒ€μž„ νƒ€μž…μ€ μ „ν˜€ μ€‘μš”ν•˜μ§€ μ•Šλ‹€.

선택은 컴파일 νƒ€μž„μ—, 였직 λ§€κ°œλ³€μˆ˜μ˜ μ»΄νŒŒμΌνƒ€μž„ νƒ€μž…μ— μ˜ν•΄ 이뀄진닀.

μ½”λ“œ 52-1의 CollectionClassifier μ˜ˆμ—μ„œ ν”„λ‘œκ·Έλž¨μ˜ μ›λž˜ μ˜λ„λŠ” λ§€κ°œλ³€μˆ˜μ˜ λŸ°νƒ€μž„ νƒ€μž…μ— κΈ°μ΄ˆν•΄ μ μ ˆν•œ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ‘œ μžλ™ λΆ„λ°°ν•˜λŠ” κ²ƒμ΄μ—ˆλ‹€. μ½”λ“œ 52-2의 Wine μ˜ˆμ—μ„œμ˜ name λ©”μ„œλ“œμ™€ λ˜‘κ°™μ΄ 말이닀.

κ°€λ³€ 인수λ₯Ό μ‚¬μš©ν•˜λŠ” λ©”μ„œλ“œλΌλ©΄ λ‹€μ€‘μ •μ˜λ₯Ό μ•„μ˜ˆ ν•˜μ§€ 말아야 ν•œλ‹€.(μ•„μ΄ν…œ 53의 μ˜ˆμ™Έ μ°Έκ³ )

  • λ‹€μ€‘μ •μ˜ν•˜λŠ” λŒ€μ‹  λ©”μ„œλ“œ 이름을 λ‹€λ₯΄κ²Œ μ§€μ–΄μ£ΌλŠ” 길도 항상 μ—΄λ € μžˆμœΌλ‹ˆ 말이닀.

ObjectOutputStream μ˜ˆμ‹œ

  • 이 클래슀의 write λ©”μ„œλ“œλŠ” λͺ¨λ“  κΈ°λ³Έ νƒ€μž…κ³Ό 일뢀 μ°Έμ‘° νƒ€μž…μš© λ³€ν˜•μ„ 가지고 μžˆλ‹€. 그런데 λ‹€μ€‘μ •μ˜κ°€ μ•„λ‹Œ λͺ¨λ“  λ©”μ„œλ“œμ— λ‹€λ₯Έ 이름을 μ§€μ–΄μ£ΌλŠ” 길을 νƒν–ˆλ‹€.
  • writeBoolean(boolean), writeInt(int), writeLong(long) 같은 식이닀.
  • 이 방식이 λ‹€μ€‘μ •μ˜λ³΄λ‹€ λ‚˜λŠ” 또 λ‹€λ₯Έ 점은 read λ©”μ„œλ“œμ˜ 이름과 짝을 λ§žμΆ”κΈ° μ’‹λ‹€λŠ” 것이닀. ObjectInputStream 클래슀의 read λ©”μ„œλ“œλŠ” μ‹€μ œλ‘œλ„ readBoolean(boolean), readInt(int), readLong(long) μ΄λ ‡κ²Œ λ˜μ–΄ μžˆλ‹€.

μƒμ„±μžμ˜ 이름을 λ‹€λ₯΄κ²Œ 지을 수 μ—†μœΌλ‹ˆ λ‘λ²ˆμ§Έ μƒμ„±μžλΆ€ν„°λŠ” 무쑰건 λ‹€μ€‘μ •μ˜κ°€ λœλ‹€.

  • 정적 νŒ©ν„°λ¦¬λΌλŠ” λŒ€μ•ˆμ„ ν™œμš©ν•  수 μžˆλŠ” κ²½μš°κ°€ λ§Žλ‹€.
  • λ˜ν•œ μƒμ„±μžλŠ” μž¬μ •μ˜ ν•  수 μ—†μœΌλ‹ˆ λ‹€μ€‘μ •μ˜μ™€ μž¬μ •μ˜κ°€ 혼용될 걱정은 넣어둬도 λœλ‹€.
  • μ—¬λŸ¬ μƒμ„±μžκ°€ 같은 수의 λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„μ•Ό ν•˜λŠ” 경우λ₯Ό μ™„μ „νžˆ ν”Όν•΄κ°ˆ μˆ˜λŠ” 없을 ν…Œλ‹ˆ 그럴 λ•Œλ₯Ό λŒ€λΉ„ν•΄ μ•ˆμ „ λŒ€μ±…μ„ λ°°μ›Œλ‘λ©΄ 도움이 될 것이닀.

λ§€κ°œλ³€μˆ˜ μˆ˜κ°€ 같은 λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œκ°€ λ§Žλ”λΌλ„ 그쀑 μ–΄λŠ 것이 주어진 λ§€κ°œλ³€μˆ˜ 집합을 μ²˜λ¦¬ν• μ§€κ°€ λͺ…ν™•νžˆ κ΅¬λΆ„λœλ‹€λ©΄ ν—·κ°ˆλ¦΄ 일은 없을 것이닀.

즉 λ§€κ°œλ³€μˆ˜ 쀑 ν•˜λ‚˜ 이상이 "근본적으둜 λ‹€λ₯΄λ‹€" λ©΄ ν—·κ°ˆλ¦΄ 일이 μ—†λ‹€. 근본적으둜 λ‹€λ₯΄λ‹€λŠ” 건 두 νƒ€μž…μ˜ 값을 μ„œλ‘œ μ–΄λŠ μͺ½μœΌλ‘œλ“  ν˜•λ³€ν™˜ν•  수 μ—†λ‹€λŠ” λœ»μ΄λ‹€. 이 쑰건만 μΆ©μ‘±ν•˜λ©΄ μ–΄λŠ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€κ°€ λ§€κ°œλ³€μˆ˜λ“€μ˜ λŸ°νƒ€μž„ νƒ€μž…λ§ŒμœΌλ‘œ κ²°μ •λœλ‹€.

  • μžλ°” 4κΉŒμ§€λŠ” λͺ¨λ“  κΈ°λ³Έ νƒ€μž…μ΄ λͺ¨λ“  μ°Έμ‘° νƒ€μž…κ³Ό 근본적으둜 λ‹¬λžμ§€λ§Œ μžλ°” 5μ—μ„œ μ˜€ν† λ°•μ‹±μ΄ λ„μž…λ˜λ©΄μ„œ ν‰ν™”λ‘­λ˜ μ‹œλŒ€κ°€ 막을 λ‚΄λ Έλ‹€.

핡심 정리

일반적으둜 λ§€κ°œλ³€μˆ˜ μˆ˜κ°€ 같을 λ•ŒλŠ” λ‹€μ€‘μ •μ˜λ₯Ό ν”Όν•˜λŠ”κ²Œ μ’‹λ‹€. 
특히 μƒμ„±μžλΌλ©΄ 이 쑰언을 λ”°λ₯΄κΈ°κ°€ λΆˆκ°€λŠ₯ν•  μˆ˜μžˆλ‹€. 그럴 λ•ŒλŠ” ν—·κ°ˆλ¦΄ λ§Œν•œ λ§€κ°œλ³€μˆ˜λŠ” ν˜•λ³€ν™˜ν•˜μ—¬ μ •ν™•ν•œ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œκ°€ μ„ νƒλ˜λ„λ‘ ν•΄μ•Ό ν•œλ‹€. 
이것이 λΆˆκ°€λŠ₯ν•˜λ©΄ μ˜ˆμ»¨λŒ€ κΈ°μ‘΄ 클래슀λ₯Ό μˆ˜μ •ν•΄ μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Όν•  λ•ŒλŠ” 같은 객체λ₯Ό μž…λ ₯λ°›λŠ” 닀쀑 μ •μ˜ λ©”μ„œλ“œλ“€μ΄ λͺ¨λ‘ λ™μΌν•˜κ²Œ λ™μž‘ν•˜λ„λ‘ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€. 

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