Item 26. Raw Type

Raw Type은 μ‚¬μš©ν•˜μ§€ 말라

μ œλ„€λ¦­ νƒ€μž…μ„ μ •μ˜ν•˜κ²Œ 되면 λ§€κ°œλ³€μˆ˜ νƒ€μž…μ΄ μ •μ˜λ˜μ§€ μ•Šμ€ Raw Typeμ΄λΌλŠ” 것이 μƒκΈ°κ²Œ λœλ‹€.(List<E> -> List) μ΄λŸ¬ν•œ Raw Type을 μ•„λž˜μ™€ 같이 κ·Έλƒ₯ μ‚¬μš©ν•˜κ²Œ 되면 μ»΄νŒŒμΌλŸ¬λŠ” κ²½κ³ λ₯Ό λ„μš°κ²Œ λœλ‹€.(그만큼 μœ„ν—˜ν•œ μ•ˆν‹° νŒ¨ν„΄)

class Main {
    public static void main(String[] args) {
        List list = new ArrayList(); // Raw use of parameterized class 'List'
        list.add("Hello"); // Unchecked call to 'add(E)' as a member of raw type 'java.util.List'
        Object o = list.get(0);// 컴파일러 경고
        System.out.println(o);
        Integer i = (Integer) o; // 컴파일 성곡, λŸ°νƒ€μž„ μ—λŸ¬
        System.out.println(i);
    }
}

ν•˜μ§€λ§Œ μ—­μ‹œ νƒ€μž… λ³€ν™˜μ„ μ‹œλ„ν•˜μ—¬ ν• λ‹Ήν•˜λ €κ³  ν•˜λŠ” κ²½μš°μ—” μ»΄νŒŒμΌμ€ μ„±κ³΅ν•˜κ³ , λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” μ‹¬κ°ν•œ λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. ν•΄κ²° 방법은 κ°„λ‹¨ν•˜κ²Œλ„ μ œλ„€λ¦­ νƒ€μž…μ„ μ‚¬μš©ν•˜μ—¬ μ»΄νŒŒμΌλŸ¬μ—κ²Œ νƒ€μž…μ„ κ°•μ œν•˜λ„λ‘ ν•˜λ©΄ λœλ‹€.

class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Hello");
        String s = list.get(0);
        System.out.println(s);
        Integer i = (Integer) s; // 컴파일 μ—λŸ¬
    }
}

이처럼 Raw Type은 μ œλ„€λ¦­ νƒ€μž…μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  μ‚¬μš©ν•˜κ²Œ 되면 생성할 수 μžˆλŠ”λ°, μ ˆλŒ€ μ¨μ„œλŠ” μ•ˆ λ˜λŠ” νƒ€μž…μ΄λ‹€. ν•˜μ§€λ§Œ 컴파일러 μƒμ—μ„œ Raw Type을 ν—ˆμš©ν•˜λŠ” μ΄μœ λŠ” μ œλ„€λ¦­ νƒ€μž…μ΄ λ„μž…λ˜κΈ° 전에 μ‚¬μš©ν•˜λ˜ μ½”λ“œμ™€μ˜ ν˜Έν™˜μ„±μ„ μœ„ν•΄ λ„μž…λœ κ²ƒμ΄λ‹ˆ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

List vs List<Object>

ObjectλŠ” λͺ¨λ“  클래슀의 μ΅œμƒμœ„ 클래슀이기 λ•Œλ¬Έμ— List같은 Raw Typeκ³Ό λ™μΌν•˜κ²Œ λ™μž‘ν•œλ‹€κ³  생각할 수 μžˆμ§€λ§Œ, μ‹€μ œλ‘œλŠ” 차이가 μžˆλ‹€.

  • List: νƒ€μž…μ„ μ™„μ „νžˆ μ²΄ν¬ν•˜μ§€ μ•ŠμŒ

  • List<Object>: λͺ¨λ“  νƒ€μž…μ„ ν—ˆμš©ν•œλ‹€λŠ” μ˜μ‚¬λ₯Ό λͺ…ν™•νžˆ μ •μ˜, νƒ€μž…μ„ 체크

μ•„λž˜ μ˜ˆμ‹œ μ½”λ“œλ₯Ό 보면 ListλŠ” List<String>을 λ„˜κ²¨ 받을 수 μžˆμ§€λ§Œ, List<Object>λŠ” List<String>을 λ„˜κ²¨ 받을 수 μ—†λ‹€. μ΄λŠ” μ œλ„€λ¦­ ν•˜μœ„ νƒ€μž… κ·œμΉ™μ— μ˜ν•΄ List<String>은 List<Object>의 ν•˜μœ„ νƒ€μž…μ΄ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

// List
class Main1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        unsafeAdd(list, Integer.valueOf(42));
        String s = list.get(0); // λŸ°νƒ€μž„ μ—λŸ¬, Exception in thread "main" java.lang.ClassCastException
    }

    private static void unsafeAdd(List list, Object o) {
        list.add(o);
    }
}

// List<Object>
class Main2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        unsafeAdd(list, Integer.valueOf(42)); // 컴파일 μ—λŸ¬, Required type: List<Object> Provided: List<String>
    }

    private static void unsafeAdd(List<Object> list, Object o) {
        list.add(o);
    }
}

Wildcard Type(μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…)

Raw Type을 μ‚¬μš©ν•˜λ©΄ λͺ¨λ“  νƒ€μž…μ„ ν—ˆμš©ν•  수 μžˆμ§€λ§Œ, μ΄λŠ” μœ„ν—˜ν•œ 방법이닀. List<Object> 같이 μ‚¬μš©ν•˜λŠ” 것은 μ œλ„€λ¦­ ν•˜μœ„ νƒ€μž… κ·œμΉ™μ— μ˜ν•΄ List<String>을 λ„˜κ²¨ 받을 수 μ—†κΈ° λ•Œλ¬Έμ— λͺ¨λ“  νƒ€μž…μ„ ν—ˆμš©ν•˜λŠ” 방법이 μ•„λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ?λ₯Ό μ‚¬μš©ν•œ μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

class Main2 {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();
        unsafeAddWildcard(list1, list2);
        unsafeAddRaw(list1, list2);
    }

    private static void unsafeAddWildcard(List<?> list1, List<?> list2) {
        list1.add(list2.get(0)); // incompatible types: java.lang.Object cannot be converted to capture#1 of ?
    }

    private static void unsafeAddRaw(List list1, List list2) {
        list1.add(list2.get(0));
    }
}

Raw Type은 νƒ€μž… 체크λ₯Ό μ „ν˜€ ν•˜κ³  μžˆμ§€ μ•Šμ•„, μ μ ˆν•˜μ§€ μ•Šμ€ νƒ€μž…μ„ λ„˜κ²¨ 받아도 컴파일 μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ€ νƒ€μž… 체크λ₯Ό ν•˜κ³  있기 λ•Œλ¬Έμ— λŸ°νƒ€μž„ μ—λŸ¬λ₯Ό λ°©μ§€ν•  수 μžˆλ‹€.

Raw Type을 μ‚¬μš©ν•˜λŠ” 경우

Raw Type을 μ§μ ‘μ μœΌλ‘œ μ‚¬μš©ν•˜λŠ” κ²½μš°λŠ” μžˆμ–΄μ„œλŠ” μ•ˆλ˜μ§€λ§Œ μ•„λž˜μ™€ 같은 κ²½μš°μ—λŠ” Raw Type을 μ‚¬μš©ν•΄μ•Όν•œλ‹€.

  • class λ¦¬ν„°λŸ΄: List.class, String[].class, int.classλŠ” ν—ˆμš©λ˜μ§€λ§Œ List<String>.classλŠ” ν—ˆμš©λ˜μ§€ μ•ŠμŒ

  • instanceof μ—°μ‚°μž: instanceof List<String>은 ν—ˆμš©λ˜μ§€ μ•ŠμŒ

    • λŸ°νƒ€μž„μ—λŠ” μ œλ„€λ¦­ νƒ€μž… 정보가 μ§€μ›Œμ§€κΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•  수 μ—†μŒ

Last updated

Was this helpful?