Item 32. Varargs

μ œλ„€λ¦­κ³Ό κ°€λ³€μΈμˆ˜λ₯Ό ν•¨κ»˜ μ“Έ λ•ŒλŠ” μ‹ μ€‘ν•˜λΌ

싀체화 λΆˆκ°€νƒ€μž…(거의 λͺ¨λ“  μ œλ„€λ¦­κ³Ό λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…)은 λŸ°νƒ€μž„μ— μ»΄νŒŒμΌνƒ€λ°λ³΄λ‹€ νƒ€μž… κ΄€λ ¨ 정보λ₯Ό 적게 λ‹΄κ³  μžˆλ‹€. 이런 νŠΉμ§• λ•Œλ¬Έμ— 싀체화 λΆˆκ°€ νƒ€μž…μœΌλ‘œ varaargsλ₯Ό μ„ μ–Έν•˜λ©΄ μ»΄νŒŒμΌλŸ¬μ—μ„œ κ²½κ³ λ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

class Main {

    public static void main(String[] args) {
        dangerous(List.of("There be dragons!")); // Warning, Unchecked generics array creation for varargs parameter 
    }

    // Warning, Possible heap pollution from parameterized vararg type
    private static void dangerous(List<String>... stringLists) {
        List<Integer> intList = List.of(42);
        Object[] objects = stringLists;
        objects[0] = intList; // νž™ μ˜€μ—Ό λ°œμƒ
        String s = stringLists[0].get(0); // ν˜•λ³€ν™˜ 도쀑 ClassCastException λ°œμƒ
    }
}

μœ„ μ½”λ“œμ²˜λŸΌ κ°€λ³€μΈμˆ˜λ₯Ό μ‚¬μš©ν•˜κ²Œ λ˜λ©΄μ„œ λ§Žμ€ 경고듀이 λ°œμƒν•˜κ³ , 잘λͺ»λœ νƒ€μž…μ΄ μ „λ‹¬λ˜μ–΄λ„ λŸ°νƒ€μž„μ—μ•Ό μ•Œ 수 있게 λœλ‹€.

κ°€λ³€μΈμˆ˜ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” 이유

item 28μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ μ œλ„€λ¦­ 배열은 μ»΄νŒŒμΌλŸ¬μ—μ„œ μ•„μ˜ˆ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¨λ‹€. ν•˜μ§€λ§Œ κ°€λ³€μΈμˆ˜λŠ” μ»΄νŒŒμΌλŸ¬μ—μ„œ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€κ³  μžˆμ§€ μ•Šμ€λ°, 이 μ΄μœ λŠ” μ‹€μ œ μ½”λ“œ μž‘μ„± μ‹œ λ§Žμ€ 이점을 쀄 수 μžˆμ–΄ λͺ¨μˆœμ μΈ 점을 μˆ˜μš©ν•˜μ—¬ κ°€λ³€μΈμˆ˜λ₯Ό ν—ˆμš©ν•˜κ³  μžˆλ‹€. λŒ€ν‘œμ μœΌλ‘œ Arrays.asList(), Collections.addAll() 등이 μžˆλ‹€.(이듀은 νƒ€μž… μ•ˆμ „μ„ 보μž₯ν•˜κ³  μžˆμ–΄ 문제 없이 μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.)

@SafeVarargs

μžλ°” 7 μ „μ—λŠ” λ°œμƒν•  수 μžˆλŠ” κ²½κ³ λ₯Ό 숨기기 μœ„ν•΄ @SuppressWarnings("unchecked") μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ˜€λ‹€. ν•˜μ§€λ§Œ 이 μ–΄λ…Έν…Œμ΄μ…˜μ€ λ‹€λ₯Έ 문제λ₯Ό μ•Œλ €μ£ΌλŠ” κ²½κ³ κΉŒμ§€ 숨길 수 있기 λ•Œλ¬Έμ— μžλ°” 7μ—μ„œλŠ” @SafeVarargs μ–΄λ…Έν…Œμ΄μ…˜μ΄ μΆ”κ°€λ˜μ—ˆλ‹€. λ‹€μŒκ³Ό 같은 쑰건을 λ§Œμ‘±ν•˜λŠ” ν™•μ‹€ν•œ κ²½μš°μ—λ§Œ @SafeVarargs μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•΄μ•Ό ν•˜λ©°, μ μš©λ˜μ§€ μ•Šμ€ varargsλŠ” μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹λ‹€.

  • κ°€λ³€μΈμˆ˜λ‘œ λ§Œλ“€μ–΄μ§„ 배열에 아무것도 μ €μž₯ν•˜μ§€ μ•ŠμŒ

  • ν•΄λ‹Ή λ°°μ—΄μ˜ μ°Έμ‘°κ°€ λ°–μœΌλ‘œ λ…ΈμΆœλ˜μ§€ μ•ŠμŒ

  • μˆœμˆ˜ν•˜κ²Œ μΈμˆ˜λ“€μ„ μ „λ‹¬ν•˜λŠ” 일만 μˆ˜ν–‰

class Main {

    @SafeVarargs
    static <T> List<T> flatten(List<? extends T>... lists) { // κ°€λ³€μΈμˆ˜λ‘œ λ§Œλ“€μ–΄μ§„ 배열에 아무것도 μ €μž₯ν•˜μ§€ μ•ŠμŒ
        List<T> result = new ArrayList<>();
        for (List<? extends T> list : lists) { // μˆœμˆ˜ν•˜κ²Œ μΈμˆ˜λ“€μ„ μ „λ‹¬ν•˜λŠ” 일만 μˆ˜ν–‰
            result.addAll(list);
        }
        return result; // ν•΄λ‹Ή λ°°μ—΄ μ°Έμ‘°κ°€ λ°–μœΌλ‘œ λ…ΈμΆœλ˜μ§€ μ•ŠμŒ
    }
}

List.of() μ‚¬μš©

@SaveVarargs μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹Œ, List.of()λ₯Ό μ‚¬μš©ν•˜λŠ” 방법도 μžˆλ‹€. List.of()λŠ” κ°€λ³€μΈμˆ˜λ₯Ό λ°›λŠ” λ©”μ„œλ“œμ΄λ©°, 이미 @SaveVarargs μ–΄λ…Έν…Œμ΄μ…˜μ΄ μ μš©λ˜μ–΄ 있기 λ•Œλ¬Έμ— μ‚¬μš© μ‹œ κ²½κ³ κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œκ°€ 비ꡐ적 λ³΅μž‘ν•΄μ§€μ§€λ§Œ, 이미 λ§Œλ“€μ–΄μ§„ κ²€μ¦λœ μ½”λ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 더 쒋은 방법이 될 수 μžˆλ‹€.

class Main {

    static <T> List<T> flatten(List<List<? extends T>> lists) {
        List<T> result = new ArrayList<>();
        for (List<? extends T> list : lists) {
            result.addAll(list);
        }
        return result;
    }

    public static void main(String[] args) {
        List<String> flatList = flatten(List.of(List.of("a", "b"), List.of("c", "d")));
        System.out.println(flatList); // [a, b, c, d]
    }
}

Last updated

Was this helpful?