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

μ»΄νŒŒμΌνƒ€μž„μ— κ²°μ •λ˜λŠ” λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œ

λ‹€μŒμ€ μ»¬λ ‰μ…˜μ„ 집합, 리슀트, κ·Έ μ™Έλ‘œ κ΅¬λΆ„ν•˜κ³ μž λ§Œλ“  ν”„λ‘œκ·Έλž¨μ΄λ‹€.

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));
    }
}

"집합", "리슀트", "κ·Έ μ™Έ"λ₯Ό μ°¨λ‘€λ‘œ 좜λ ₯ν•  것 κ°™μ§€λ§Œ, μ‹€μ œλ‘œ μˆ˜ν–‰ν•΄λ³΄λ©΄ "κ·Έ μ™Έ"만 μ„Έλ²ˆ 연달아 좜λ ₯ν•œλ‹€.

μ™œλƒν•˜λ©΄ λ‹€μ€‘μ •μ˜λœ μ„Έ classify 쀑 μ–΄λŠ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€κ°€ μ»΄νŒŒμΌνƒ€μž„μ— 정해지기 λ•Œλ¬Έμ΄λ‹€.

μ»΄νŒŒμΌνƒ€μž„μ—λŠ” for λ¬Έ μ•ˆμ˜ cλŠ” 항상 Collection<?> νƒ€μž…μ΄λ‹€.

λŸ°νƒ€μž„μ—λŠ” νƒ€μž…μ΄ 맀번 λ‹¬λΌμ§€μ§€λ§Œ, ν˜ΈμΆœν•  λ©”μ„œλ“œλ₯Ό μ„ νƒν•˜λŠ” λ°λŠ” 영ν–₯을 주지 λͺ»ν•œλ‹€.

λ”°λΌμ„œ μ»΄νŒŒμΌνƒ€μž„μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…μ„ κΈ°μ€€μœΌλ‘œ 항상 μ„Έ 번째 λ©”μ„œλ“œμΈ classify(Collection<?>)만 ν˜ΈμΆœν•˜λŠ” 것이닀.


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

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

μ»΄νŒŒμΌνƒ€μž„μ— κ·Έ μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ΄ λ¬΄μ—‡μ΄μ—ˆλƒλŠ” 상관없닀. λ‹€μŒ μ½”λ“œλŠ” μ΄λŸ¬ν•œ 상황을 ꡬ체적으둜 보여쀀닀.

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());
    }
}

Wine ν΄λž˜μŠ€μ— μ •μ˜λœ name λ©”μ„œλ“œλŠ” ν•˜μœ„ 클래슀인 SparklingWineκ³Ό Champagneμ—μ„œ μž¬μ •μ˜λœλ‹€.

μ˜ˆμƒν•œ κ²ƒμ²˜λŸΌ 이 ν”„λ‘œκ·Έλž¨μ€ "포도주", "λ°œν¬μ„± 포도주", "μƒ΄νŽ˜μΈ" 을 μ°¨λ‘€λ‘œ 좜λ ₯ν•œλ‹€.

λ‹€μ€‘μ •μ˜ 문제λ₯Ό νšŒν”Όν•˜λŠ” 방법 1 :: instanceof

CollectionClassifierμ—μ„œμ˜ μ»΄νŒŒμΌνƒ€μž„ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œ κ²°μ • λ¬Έμ œλŠ” λͺ¨λ“  classify λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜λ‘œ ν•©μΉœ ν›„ instanceof둜 λͺ…μ‹œμ μœΌλ‘œ κ²€μ‚¬ν•˜λ©΄ λ§λ”νžˆ ν•΄κ²°λœλ‹€.

public static String classify(Collection<?> c) {
    return c instanceof Set  ? "집합" :
            c instanceof List ? "리슀트" : "κ·Έ μ™Έ";
}

ν—·κ°ˆλ¦΄ 여지가 μžˆλŠ” λ‹€μ€‘μ •μ˜λŠ” μ΅œλŒ€ν•œ μ§€μ–‘ν•˜μž

κ°œλ°œμžμ—κ²ŒλŠ” μž¬μ •μ˜κ°€ μ •μƒμ μœΌλ‘œ 보이고, λ‹€μ€‘μ •μ˜κ°€ μ˜ˆμ™Έμ μœΌλ‘œ 보일 수 μžˆλ‹€.

즉, μž¬μ •μ˜ν•œ λ©”μ„œλ“œλŠ” κ°œλ°œμžκ°€ κΈ°λŒ€ν•œ λŒ€λ‘œ λ™μž‘ν•˜μ§€λ§Œ, CollectionClassifier μ˜ˆμ—μ„œ 처럼 λ‹€μ€‘μ •μ˜ν•œ λ©”μ„œλ“œλŠ” μ΄λŸ¬ν•œ κΈ°λŒ€λ₯Ό κ°€λ³κ²Œ λ¬΄μ‹œν•œλ‹€.

ν—·κ°ˆλ¦΄ 수 μžˆλŠ” μ½”λ“œλŠ” μž‘μ„±ν•˜μ§€ μ•ŠλŠ” 게 μ’‹λ‹€. νŠΉνžˆλ‚˜ 곡개 API라면 λ”μš± μ‹ κ²½ 써야 ν•œλ‹€. λ‹€μ€‘μ •μ˜κ°€ ν˜Όλ™μ„ μΌμœΌν‚€λŠ” 상황을 μ΅œλŒ€ν•œ ν”Όν•΄μ•Ό ν•œλ‹€.

μ •ν™•νžˆ μ–΄λ–»κ²Œ μ‚¬μš©ν–ˆμ„ λ•Œ λ‹€μ€‘μ •μ˜κ°€ ν˜Όλž€μ„ μ£ΌλŠλƒμ— λŒ€ν•΄μ„œλŠ” λ…Όλž€μ˜ 여지가 μžˆλ‹€.

μ•ˆμ „ν•˜κ³  보수적으둜 κ°€λ €λ©΄ λ§€κ°œλ³€μˆ˜ μˆ˜κ°€ 같은 λ‹€μ€‘μ •μ˜λŠ” λ§Œλ“€μ§€ 말자.

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

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

λ‹€μ€‘μ •μ˜ 문제λ₯Ό νšŒν”Όν•˜λŠ” 방법 2 :: λ©”μ„œλ“œλ₯Ό λΆ„λ¦¬ν•˜μ—¬ μ •μ˜ν•˜κΈ°

ObjectOutPutStream 클래슀의 경우λ₯Ό μ‚΄νŽ΄λ³΄μž. 이 클래슀의 write λ©”μ„œλ“œλŠ” λͺ¨λ“  κΈ°λ³Έ νƒ€μž…κ³Ό 일뢀 μ°Έμ‘° νƒ€μž…μš© λ³€ν˜•μ„ 가지고 μžˆλ‹€.

그런데 λ‹€μ€‘μ •μ˜κ°€ μ•„λ‹Œ, λͺ¨λ“  λ©”μ„œλ“œμ— λ‹€λ₯Έ 이름을 μ§€μ–΄μ£ΌλŠ” 길을 νƒν–ˆλ‹€. writeBoolean(boolea), writeInt(int), writeLong(long) 처럼.

이 λ°©μ‹μ˜ μž₯점은 read λ©”μ„œλ“œμ˜ 이름과 짝을 λ§žμΆ”κΈ° μ’‹λ‹€λŠ” 점이닀. readBoolean(), readInt(), readLong() 처럼.

μ‹€μ œλ‘œλ„ μ΄λ ‡κ²Œ λ˜μ–΄ μžˆλ‹€.

λ‹€μ€‘μ •μ˜λ₯Ό νšŒν”Όν•˜λŠ” 방법 3 :: 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ μ‚¬μš©

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

ν•˜μ§€λ§Œ 정적 νŒ©ν„°λ¦¬λΌλŠ” λŒ€μ•ˆμ„ ν™œμš©ν•  수 μžˆλŠ” κ²½μš°κ°€ λ§Žλ‹€. (item 1) λ˜ν•œ μƒμ„±μžλŠ” μž¬μ •μ˜ν•  수 μ—†μœΌλ‹ˆ λ‹€μ€‘μ •μ˜μ™€ μž¬μ •μ˜κ°€ 혼용될 걱정은 ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

κ·Έλž˜λ„ μ—¬λŸ¬ μƒμ„±μžκ°€ 같은 수의 λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„μ•Ό ν•˜λŠ” 경우λ₯Ό μ™„μ „νžˆ ν”Όν•΄κ°ˆ μˆ˜λŠ” μ—†μœΌλ‹ˆ, 그럴 λ•Œλ₯Ό λŒ€λΉ„ν•΄ μ•ˆμ „ λŒ€μ±…μ„ λ°°μ›Œλ‘λ©΄ 도움이 될 것이닀.

λ‹€μ€‘μ •μ˜λ₯Ό νšŒν”Όν•˜λŠ” 방법 4 :: 근본적으둜 λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜ νƒ€μž… μ‚¬μš©

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

즉, λ§€κ°œλ³€μˆ˜ 쀑 ν•˜λ‚˜ 이상이 "근본적으둜 λ‹€λ₯΄λ‹€"λ©΄ ν—·κ°ˆλ¦΄ 일이 μ—†λ‹€.

근본적으둜 λ‹€λ₯΄λ‹€λŠ” 것은 null이 μ•„λ‹Œ 두 νƒ€μž…μ˜ 값을 μ„œλ‘œ μ–΄λŠ μͺ½μœΌλ‘œλ“  ν˜•λ³€ν™˜ν•  수 μ—†λ‹€λŠ” λœ»μ΄λ‹€.

이 쑰건만 μΆ©μ‘±ν•˜λ©΄ μ–΄λŠ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€κ°€ λ§€κ°œλ³€μˆ˜λ“€μ˜ λŸ°νƒ€μž„ νƒ€μž…λ§ŒμœΌλ‘œ κ²°μ •λœλ‹€.

λ”°λΌμ„œ μ»΄νŒŒμΌνƒ€μž„ νƒ€μž…μ—λŠ” 영ν–₯을 받지 μ•Šκ²Œ 되고, ν˜Όλž€μ„ μ£ΌλŠ” 주된 원인이 사라진닀.

λ‹€μ€‘μ •μ˜λ₯Ό λ°©ν•΄ν•˜λŠ” 쑴재 1 :: μ˜€ν† λ°•μ‹±(근본적으둜 λ‹€λ₯Έ νƒ€μž…μ„ λ°©ν•΄)

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

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ„ μ‚΄νŽ΄λ³΄μž.

public class SetList {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();
        List<Integer> list = new ArrayList<>();

        for (int i = -3; i < 3; i++) {
            set.add(i);
            list.add(i);
        }
        for (int i = 0; i < 3; i++) {
            set.remove(i);
            list.remove(i);
        }
        System.out.println(set + " " + list);
    }
}

이 ν”„λ‘œκ·Έλž¨μ€ -3λΆ€ν„° 2κΉŒμ§€μ˜ μ •μˆ˜λ₯Ό μ •λ ¬λœ 집합과 λ¦¬μŠ€νŠΈμ— 각각 μΆ”κ°€ν•œ λ‹€μŒ, μ–‘μͺ½μ— λ˜‘κ°™μ΄ remove λ©”μ„œλ“œλ₯Ό μ„Έ 번 ν˜ΈμΆœν•œλ‹€.

그러면 이 ν”„λ‘œκ·Έλž¨μ€ 음이 μ•„λ‹Œ κ°’, 즉 0, 1, 2λ₯Ό μ œκ±°ν•œ ν›„ "[-3, -2, -1] [-3, -2, -1]" 을 좜λ ₯ν•˜λ¦¬λΌ μ˜ˆμƒν•  것이닀.

ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ” μ§‘ν•©μ—μ„œλŠ” 음이 μ•„λ‹Œ 값을 μ œκ±°ν•˜κ³ , λ¦¬μŠ€νŠΈμ—μ„œλŠ” ν™€μˆ˜λ₯Ό μ œκ±°ν•œ ν›„ "[-3, -2, -1] [-2, 0, 2]" λ₯Ό 좜λ ₯ν•œλ‹€. 무슨 일일까?


set.remove(i)의 μ‹œκ·Έλ‹ˆμ²˜λŠ” remove(Object)λ‹€. λ‹€μ€‘μ •μ˜λœ λ‹€λ₯Έ λ©”μ„œλ“œκ°€ μ—†μœΌλ‹ˆ κΈ°λŒ€ν•œ λŒ€λ‘œ λ™μž‘ν•˜μ—¬ μ§‘ν•©μ—μ„œ 0 μ΄μƒμ˜ μˆ˜λ“€μ„ μ œκ±°ν•œλ‹€.

ν•œνŽΈ, list.remove(i)λŠ” λ‹€μ€‘μ •μ˜λœ remove(int index)λ₯Ό μ„ νƒν•œλ‹€.

그런데 이 removeλŠ” 'μ§€μ •ν•œ μœ„μΉ˜'의 μ›μ†Œλ₯Ό μ œκ±°ν•˜λŠ” κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€!

이 λ¬Έμ œλŠ” list.remove의 인수λ₯Ό Integer둜 ν˜•λ³€ν™˜ν•˜μ—¬ μ˜¬λ°”λ₯Έ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ₯Ό μ„ νƒν•˜κ²Œ ν•˜λ©΄ ν•΄κ²°λœλ‹€.

ν˜Ήμ€ Integer.valueOfλ₯Ό μ΄μš©ν•΄ iλ₯Ό Integer둜 λ³€ν™˜ν•œ ν›„ list.remove에 전달해도 λœλ‹€.

λ‹€μ€‘μ •μ˜λ₯Ό λ°©ν•΄ν•˜λŠ” 쑴재 2 :: λžŒλ‹€μ™€ λ©”μ„œλ“œ μ°Έμ‘°

μžλ°” 8μ—μ„œ λ„μž…ν•œ λžŒλ‹€μ™€ λ©”μ„œλ“œ μ°Έμ‘° μ—­μ‹œ λ‹€μ€‘μ •μ˜ μ‹œμ˜ ν˜Όλž€μ„ ν‚€μ› λ‹€.

new Thread(System.out::println).start();

Executors.newCachedThreadPool().submit(System.out::println);

2번만 컴파일 였λ₯˜κ°€ λ‚œλ‹€. λ„˜κ²¨μ§„ μΈμˆ˜λŠ” λͺ¨λ‘ System.out::println으둜 λ˜‘κ°™κ³ , μ–‘μͺ½ λͺ¨λ‘ Runnable을 λ°›λŠ” ν˜•μ œ λ©”μ„œλ“œλ₯Ό λ‹€μ€‘μ •μ˜ν•˜κ³  μžˆλ‹€.

그런데 μ™œ ν•œμͺ½λ§Œ μ‹€νŒ¨ν• κΉŒ? 원인은 λ°”λ‘œ submit 닀쀑 μ •μ˜ λ©”μ„œλ“œ μ€‘μ—λŠ” Callableλ₯Ό λ°›λŠ” λ©”μ„œλ“œλ„ μžˆλ‹€λŠ” 데 μžˆλ‹€.

<T> Future<T> submit(Callable<T> task);

ν•˜μ§€λ§Œ λͺ¨λ“  println이 voidλ₯Ό λ°˜ν™˜ν•˜λ‹ˆ, λ°˜ν™˜κ°’μ΄ μžˆλŠ” Callableκ³Ό ν—·κ°ˆλ¦΄ λ¦¬λŠ” μ—†λ‹€κ³  생각할지도 λͺ¨λ₯Έλ‹€.

합리적인 μΆ”λ‘ μ΄μ§€λ§Œ, λ‹€μ€‘μ •μ˜ ν•΄μ†Œ(resolution : μ μ ˆν•œ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ₯Ό μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜)λŠ” μ΄λ ‡κ²Œ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.

λ§Œμ•½ println이 λ‹€μ€‘μ •μ˜ 없이 단 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν–ˆλ‹€λ©΄ 이 submit λ©”μ„œλ“œ 호좜이 μ œλŒ€λ‘œ μ»΄νŒŒμΌλμ„ 것이닀.

μ§€κΈˆμ€ 참쑰된 λ©”μ„œλ“œμ™€ ν˜ΈμΆœν•œ λ©”μ„œλ“œ μ–‘μͺ½ λ‹€ λ‹€μ€‘μ •μ˜λ˜μ–΄, λ‹€μ€‘μ •μ˜ ν•΄μ†Œ μ•Œκ³ λ¦¬μ¦˜μ΄ 우리의 κΈ°λŒ€μ²˜λŸΌ λ™μž‘ν•˜μ§€ μ•ŠλŠ” 상황이닀.

기술적으둜 λ§ν•˜λ©΄ System.out::println은 λΆ€μ •ν™•ν•œ λ©”μ„œλ“œ μ°Έμ‘°λ‹€.

그리고 λΆ€μ •ν™•ν•œ λ©”μ„œλ“œ 참쑰같은 인수 ν‘œν˜„μ‹μ€ λͺ©ν‘œ νƒ€μž…μ΄ μ„ νƒλ˜κΈ° μ „μ—λŠ” κ·Έ μ˜λ―Έκ°€ 정해지지 μ•ŠκΈ° λ•Œλ¬Έμ— μ μš©μ„± ν…ŒμŠ€νŠΈ(??) λ•Œ λ¬΄μ‹œλœλ‹€.

말이 μ–΄λ €μš΄λ°, 핡심은 λ‹€μ€‘μ •μ˜λœ λ©”μ„œλ“œ(or μƒμ„±μž)듀이 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό 인수둜 받을 λ•Œ, 비둝 μ„œλ‘œ λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λΌλ„ 인수 μœ„μΉ˜κ°€ κ°™μœΌλ©΄ ν˜Όλž€μ΄ μƒκΈ΄λ‹€λŠ” 것이닀.

λ”°λΌμ„œ λ©”μ„œλ“œλ₯Ό λ‹€μ€‘μ •μ˜ν•  λ•Œ, μ„œλ‘œ λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λΌλ„ 같은 μœ„μΉ˜μ˜ 인수둜 λ°›μ•„μ„œλŠ” μ•ˆ λœλ‹€.

이 말은 μ„œλ‘œ λ‹€λ₯Έ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λΌλ„ μ„œλ‘œ 근본적으둜 λ‹€λ₯΄μ§€ μ•Šλ‹€λŠ” λœ»μ΄λ‹€.

μ»΄νŒŒμΌν•  λ•Œ λͺ…령쀄 μŠ€μœ„μΉ˜λ‘œ -Xlint:overloads λ₯Ό μ§€μ •ν•˜λ©΄ 이런 μ’…λ₯˜μ˜ λ‹€μ€‘μ •μ˜λ₯Ό 경고해쀄 것이닀.

근본적으둜 λ‹€λ₯Έ νƒ€μž…λ“€μ˜ 예

Object μ™Έμ˜ 클래슀 νƒ€μž…κ³Ό λ°°μ—΄ νƒ€μž…μ€ 근본적으둜 λ‹€λ₯΄λ‹€. Serializableκ³Ό Cloneable μ™Έμ˜ μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…κ³Ό λ°°μ—΄ νƒ€μž…λ„ 근본적으둜 λ‹€λ₯΄λ‹€.

ν•œνŽΈ, Stringκ³Ό Throwable처럼 μƒμœ„/ν•˜μœ„ 관계가 μ•„λ‹Œ 두 ν΄λž˜μŠ€λŠ” 'κ΄€λ ¨ μ—†λ‹€' κ³  ν•œλ‹€.

그리고 μ–΄λ–€ 객체도 κ΄€λ ¨ μ—†λŠ” 두 클래슀의 곡톡 μΈμŠ€ν„΄μŠ€κ°€ 될 수 없기에, κ΄€λ ¨ μ—†λŠ” ν΄λž˜μŠ€λ“€λΌλ¦¬λ„ 근본적으둜 λ‹€λ₯΄λ‹€.


이 외에도 μ–΄λ–€ λ°©ν–₯μœΌλ‘œλ„ ν˜•λ³€ν™˜ν•  수 μ—†λŠ” νƒ€μž… 쌍이 μžˆμ§€λ§Œ, μ–΄μ¨Œλ“  μ•žμ—μ„œ λ‚˜μ—΄ν•œ κ°„λ‹¨ν•œ μ˜ˆλ³΄λ‹€ λ³΅μž‘ν•΄μ§€λ©΄ λŒ€λΆ€λΆ„ ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” μ–΄λ–€ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œκ°€ 선택될지λ₯Ό κ΅¬λΆ„ν•˜κΈ° μ–΄λ €μ›Œν•  것이닀.

λ‹€μ€‘μ •μ˜λœ λ©”μ„œλ“œ 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜λŠ” κ·œμΉ™μ€ 맀우 λ³΅μž‘ν•˜λ©°, μžλ°”κ°€ λ²„μ „μ—…λ μˆ˜λ‘ 더 λ³΅μž‘ν•΄μ§€κ³  μžˆμ–΄, 이 λͺ¨λ‘λ₯Ό μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” 극히 λ“œλ¬Ό 것이닀.

λ‹€μ€‘μ •μ˜λ₯Ό μ£Όμ˜ν•˜μ§€ λͺ»ν•œ 사둀

이번 μ•„μ΄ν…œμ—μ„œ μ„€λͺ…ν•œ 지침듀을 지킀지 λͺ»ν•  μˆ˜λ„ μžˆλ‹€. 이미 λ§Œλ“€μ–΄μ§„ ν΄λž˜μŠ€κ°€ 끼어듀면 특히 더 κ·Έλ ‡λ‹€.

예λ₯Ό λ“€μ–΄ String은 μžλ°” 4 μ‹œμ ˆλΆ€ν„° ContentEquals(StringBuffer) λ©”μ„œλ“œλ₯Ό 가지고 μžˆμ—ˆλ‹€.

그런데 μžλ°” 5μ—μ„œ StringBuffer, StringBuilder, String, CharBuffer λ“±μ˜ λΉ„μŠ·ν•œ λΆ€λ₯˜μ˜ νƒ€μž…μ„ μœ„ν•œ 곡톡 μΈν„°νŽ˜μ΄μŠ€λ‘œ CharSequenceκ°€ λ“±μž₯ν•˜μ˜€κ³ , μžμ—°μŠ€λŸ½κ²Œ String에도 CharSequenceλ₯Ό 받은 contentEqualsκ°€ λ‹€μ€‘μ •μ˜λ˜μ—ˆλ‹€.

κ·Έ κ²°κ³Ό 이번 μ•„μ΄ν…œμ˜ 지침을 λŒ€λ†“κ³  μ–΄κΈ°λŠ” λͺ¨μŠ΅μ΄ λ˜μ—ˆλ‹€. λ‹€ν–‰νžˆ 이 두 λ©”μ„œλ“œλŠ” 같은 객체λ₯Ό μž…λ ₯ν•˜λ©΄ μ™„μ „νžˆ 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ£Όλ‹ˆ ν•΄λ‘œμšΈ 건 μ „ν˜€ μ—†λ‹€.

λ‹€μ€‘μ •μ˜λœ λ©”μ„œλ“œκ°€ μ™„λ²½νžˆ 같은 λ‘œμ§μ„ μˆ˜ν–‰ν•  λ•Œ? :: foward

μ–΄λ–€ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œκ°€ λΆˆλ¦¬λŠ”μ§€ λͺ°λΌλ„ κΈ°λŠ₯이 λ˜‘κ°™λ‹€λ©΄ μ•„λž˜μ™€ 같은 방법을 μ‚¬μš©ν•΄ μ•ˆμ „ν•˜κ²Œ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μžˆλ‹€.

μƒλŒ€μ μœΌλ‘œ 더 νŠΉμˆ˜ν•œ λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œμ—μ„œ 덜 νŠΉμˆ˜ν•œ (더 일반적인) λ‹€μ€‘μ •μ˜ λ©”μ„œλ“œλ‘œ 일을 λ„˜κ²¨λ²„λ¦¬λŠ” 것이닀.

public boolean contentEquals(StringBuffer sb) {
    return contentEquals((CharSequence) sb);
}
⚠️ **GitHub.com Fallback** ⚠️