Skip to content

Latest commit

ย 

History

History
319 lines (233 loc) ยท 14.8 KB

File metadata and controls

319 lines (233 loc) ยท 14.8 KB

item 32 : ์ œ๋„ค๋ฆญ๊ณผ ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์“ธ ๋•Œ๋Š” ์‹ ์ค‘ํ•˜๋ผ

1. ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ํ—ˆ์ 

1) ๊ฐ€๋ณ€์ธ์ˆ˜๋ž€?

{% hint style="info" %} ๊ฐ€๋ณ€์ธ์ˆ˜(Variable Arguments)๋ž€, ๋ฉ”์„œ๋“œ๋‚˜ ํ•จ์ˆ˜์—์„œ ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€๋ณ€์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋งํ•œ๋‹ค. {% endhint %}

์ฆ‰, ํ˜ธ์ถœ ์‹œ ์ „๋‹ฌ๋˜๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ๊ฐ€ ๋™์ž‘ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. Java์—์„œ๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ... ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์ด์šฉํ•ด ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

2) ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ๋ฌธ๋ฒ•

๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… ๋’ค์— ...์„ ๋ถ™์—ฌ ์„ ์–ธํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค:

public void printNumbers(int... numbers) {
    for (int number : numbers) {
        System.out.println(number);
    }
}

์œ„ ๋ฉ”์„œ๋“œ printNumbers๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜ int... numbers๋ฅผ ๋ฐ›์•„, ์ „๋‹ฌ๋œ ๋ชจ๋“  ์ˆซ์ž๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœํ•  ๋•Œ๋Š” ์ธ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค:

printNumbers(1); // ์ธ์ˆ˜๊ฐ€ 1๊ฐœ
printNumbers(1, 2, 3, 4); // ์ธ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ

์œ„ ์˜ˆ์ œ์—์„œ numbers๋Š” ๋ฐฐ์—ด๋กœ ์ทจ๊ธ‰๋˜๋ฉฐ, ์ „๋‹ฌ๋œ ์ธ์ˆ˜๋“ค์„ ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

3) ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ๊ทœ์น™

  1. ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋ฉ”์„œ๋“œ์—์„œ ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ: ๋ฉ”์„œ๋“œ์— ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ํ•˜๋‚˜๋งŒ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ๋ณ€์ˆ˜์—ฌ์•ผ ํ•จ: ๋‹ค๋ฅธ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ํ•ญ์ƒ ๋งˆ์ง€๋ง‰์— ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค.
public void exampleMethod(String message, int... numbers) {
    System.out.println(message);
    for (int number : numbers) {
        System.out.println(number);
    }
}

ํ•˜์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค:

// ์˜ค๋ฅ˜: ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋งˆ์ง€๋ง‰์— ์™€์•ผ ํ•จ
public void invalidMethod(int... numbers, String message) {
    // ์ฝ”๋“œ ๋‚ด์šฉ
}

4) ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ์žฅ์ 

  • ์œ ์—ฐํ•œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ: ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ „๋‹ฌํ•˜๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•˜๋‹ค.
  • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ: ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง„๋‹ค.

5) ๊ฐ€๋ณ€์ธ์ˆ˜์™€ ๋ฐฐ์—ด์˜ ์ฐจ์ด

๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด๋กœ ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ, ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐฐ์—ด์„ ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅด๋‹ค. ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ธ์ˆ˜๋ฅผ ์ฝค๋งˆ๋กœ ๊ตฌ๋ถ„ํ•ด ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด, ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐฐ์—ด์„ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ์ œ

public class VarargsExample {
    public static void main(String[] args) {
        sum(1, 2);           // 2๊ฐœ์˜ ์ธ์ˆ˜ ์ „๋‹ฌ
        sum(1, 2, 3, 4, 5);  // 5๊ฐœ์˜ ์ธ์ˆ˜ ์ „๋‹ฌ
    }

    // ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์ด์šฉํ•œ ๋ฉ”์„œ๋“œ
    public static void sum(int... numbers) {
        int total = 0;
        for (int number : numbers) {
            total += number;
        }
        System.out.println("Sum: " + total);
    }
}

์œ„ ์˜ˆ์ œ์—์„œ sum ๋ฉ”์„œ๋“œ๋Š” ์ „๋‹ฌ๋ฐ›์€ ๋ชจ๋“  ์ˆซ์ž๋ฅผ ๋”ํ•ด ํ•ฉ๊ณ„๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ํ˜ธ์ถœ ์‹œ ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜์— ์ œํ•œ์ด ์—†์œผ๋ฉฐ, ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ฐœ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋” ์œ ์—ฐํ•˜๊ณ  ํŽธ๋ฆฌํ•˜๊ฒŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ

6) ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ํ—ˆ์ 

{% hint style="danger" %} ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋ฉ”์„œ๋“œ์— ๋„˜๊ธฐ๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š”๋ฐ, ๊ตฌํ˜„ ๋ฐฉ์‹์— ํ—ˆ์ ์ด ์žˆ๋‹ค. {% endhint %}

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ ๋ฐฐ์—ด์ด ์ž๋™์œผ๋กœ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ง„๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‚ด๋ถ€๋กœ ๊ฐ์ถฐ์•ผ ํ–ˆ์„ ์ด ๋ฐฐ์—ด์„ ๊ทธ๋งŒ ํด๋ผ์ด ์–ธํŠธ์— ๋…ธ์ถœํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ varargs ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ œ๋„ค๋ฆญ์ด๋‚˜ ๋งค๊ฐœ ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์ด ํฌํ•จ๋˜๋ฉด ์•Œ๊ธฐ ์–ด๋ ค์šด ์ปดํŒŒ์ผ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

2. ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜

1) ์ œ๋„ค๋ฆญ๊ณผ varargs๋ฅผ ํ˜ผ์šฉํ•˜๋ฉด ํƒ€์ž… ์•ˆ์ „์„ฑ์ด ๊นจ์ง„๋‹ค!

import java.util.ArrayList;
import java.util.List;

public class Example {
    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
    }

    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("Hi there");
        dangerous(stringList);
    }
}
  • ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์€ ๋Ÿฐํƒ€์ž„์—๋Š” ์ปดํŒŒ์ผํƒ€์ž„๋ณด๋‹ค ํƒ€์ž… ๊ด€๋ จ ์ •๋ณด๋ฅผ ์ ๊ฒŒ ๋‹ด๊ณ  ์žˆ์Œ์„ ๋ฐฐ์› ๋‹ค.
  • ๊ฑฐ์˜ ๋ชจ๋“  ์ œ๋„ค๋ฆญ๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž… ์€ ์‹ค์ฒดํ™”๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ๋•Œ ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์œผ๋กœ varargs ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๋ณด๋‚ธ๋‹ค.
  • ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋„ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๋ฉด, ๊ทธ ํ˜ธ์ถœ์— ๋Œ€ํ•ด์„œ๋„ ๊ฒฝ๊ณ  ๋ฅผ ๋‚ธ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์˜ ๋ณ€์ˆ˜๊ฐ€ ํƒ€์ž…์ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ํž™ ์˜ค์—ผ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ๋‹ค๋ฅธ ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™ ์ƒ์„ฑํ•œ ํ˜•๋ณ€ํ™˜์ด ์‹คํŒจํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์ œ๋„ค๋ฆญ ํƒ€์ž… ์‹œ์Šคํ…œ์ด ์•ฝ์†ํ•œ ํƒ€์ž… ์•ˆ ์ „์„ฑ์˜ ๊ทผ๊ฐ„์ด ํ”๋“ค๋ ค๋ฒ„๋ฆฐ๋‹ค.

List<String>[] stringLists = new List<String>[l]; // (1)
List<Integer> intList = List.of(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[์ด.get(0); // (5)

{% hint style="danger" %} ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ? ๋‹ฌ๋ฆฌ ๋งํ•˜๋ฉด, ์ฝ”๋“œ ์œ„์˜ ์ฝ”๋“œ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋‚ด ๋ฉด์„œ ๋ฐ‘์˜ ์ฝ”๋“œ๋Š” ๊ฒฝ๊ณ ๋กœ ๋๋‚ด๋Š” ์ด์œ ๋Š” ๋ญ˜๊นŒ? {% endhint %}

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
}

๊ทธ ๋‹ต์€ ์ œ๋„ค๋ฆญ์ด๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์˜ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‹ค๋ฌด์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์–ธ์–ด ์„ค๊ณ„์ž๋Š” ์ด ๋ชจ์ˆœ์„ ์ˆ˜์šฉํ•ด์œ„์˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด Arrays.list(T... a), EnumSet.of(E first, E... set)๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค.

// Arrays.Java
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

// EnumSet.java
@SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
    EnumSet<E> result = noneOf(first.getDeclaringClass());
    result.add(first);
    for (E e : rest)
        result.add(e);
    return result;
}

2) ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜์˜ ๋ฌธ์ œ์ 

Java์—์„œ๋Š” ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์„ ์ง์ ‘ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์ง€๋งŒ, ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋Š” ํ—ˆ์šฉ๋œ๋‹ค.

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด์ด ์ƒ์„ฑ๋˜๋ฉฐ, ์ด ๋ฐฐ์—ด์˜ ํƒ€์ž…์€ ์ปดํŒŒ์ผ ์‹œ์— ๊ฒฐ์ •๋˜์ง€ ์•Š๊ณ  ๋Ÿฐํƒ€์ž„์— ๊ฒฐ์ •๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, Arrays.asList(T... a)์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํŽธ๋ฆฌํ•˜๊ฒŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๋ฐฐ์—ด์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ํƒ€์ž… ์•ˆ์ „์„ฑ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž

static <T> T[] toArray(T... args) {
    return args;
}

์œ„์˜ ๋ฉ”์„œ๋“œ๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฌธ์ œ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฐ์—ด์˜ ํƒ€์ž…์ด ๋Ÿฐํƒ€์ž„์— ๊ฒฐ์ •๋˜๋ฉฐ, ์ด๋•Œ ํƒ€์ž…์ด ์ž˜๋ชป ํŒ๋‹จ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

public static void main(String[] args) {
    String[] attributes = toArray("์ข‹์€", "๋น ๋ฅธ", "์ €๋ ดํ•œ");
}

์œ„ ์ฝ”๋“œ๋Š” ์ปดํŒŒ์ผ๋  ๋•Œ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์— ClassCastException์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” toArray ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฐ์—ด์ด ์‹ค์ œ๋กœ๋Š” Object[] ํƒ€์ž…์ด์ง€๋งŒ, String[] ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜์ด ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

3) ์•ˆ์ „ํ•˜๊ฒŒ ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

Java 7์—์„œ๋Š” @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ๋„์ž…ํ•˜์—ฌ, ๋ฉ”์„œ๋“œ ์ž‘์„ฑ์ž๊ฐ€ ๋ฉ”์„œ๋“œ๊ฐ€ ํƒ€์ž… ์•ˆ์ „ํ•จ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค. ์ด ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ ๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, @SafeVarargs๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‹ค์ œ๋กœ ํƒ€์ž… ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

๋ฉ”์„œ๋“œ๊ฐ€ ํƒ€์ž… ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

  • ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์— ๊ฐ’์„ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ: ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ๋ฎ์–ด์“ฐ์ง€ ์•Š๋Š”๋‹ค๋ฉด ์•ˆ์ „ํ•˜๋‹ค.
  • ๋ฐฐ์—ด์˜ ์ฐธ์กฐ๊ฐ€ ์™ธ๋ถ€์— ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ: ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ , ๋‚ด๋ถ€์ ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•ˆ์ „ํ•˜๋‹ค.
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

4) ์•ˆ์ „ํ•œ ์ œ๋„ค๋ฆญ Varargs ๋ฉ”์„œ๋“œ์˜ ์กฐ๊ฑด

๋‹ค์Œ ๋‘ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ์ œ๋„ค๋ฆญ Varargs ๋ฉ”์„œ๋“œ๋Š” ์•ˆ์ „ํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ๋‘ ์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์œ„๋ฐ˜๋œ๋‹ค๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

  1. Varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์— ๊ฐ’์„ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ๋ฎ์–ด์“ฐ์ง€ ์•Š๋Š”๋‹ค.
  2. ๋ฐฐ์—ด(ํ˜น์€ ๋ฐฐ์—ด์˜ ๋ณต์ œ๋ณธ)์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ์— ๋…ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐฐ์—ด์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ , ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

5) ์•ˆ์ „ํ•œ ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ

์•„๋ž˜ ์˜ˆ์‹œ๋Š” ์•ˆ์ „ํ•œ ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค. ์—ฌ๋Ÿฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ํ•ฉ์น˜๋Š” ๋ฉ”์„œ๋“œ

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

์œ„ ๋ฉ”์„œ๋“œ๋Š” @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๋ฉฐ, ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์˜ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ , ๋ฐฐ์—ด์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ „ํ•˜๋‹ค.

6) ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์˜ˆ์‹œ

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ƒ์„ฑ๋œ ๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค

static <T> T[] pickTwo(T a, T b, T c) {
    switch (ThreadLocalRandom.current().nextInt(3)) {
        case 0: return toArray(a, b);
        case 1: return toArray(a, c);
        case 2: return toArray(b, c);
    }
    throw new AssertionError(); // ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค.
}

์ด ๋ฉ”์„œ๋“œ๋Š” pickTwo ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ ClassCastException์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑ๋œ ๋ฐฐ์—ด์ด Object[] ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

7) ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ์˜ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋Š” ์™€์ผ๋“œ์นด๋“œ ํƒ€์ž…์„ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

public static void wildcardSwap(List<?> list, int i, int j) {
    wildcardSwapHelper(list, i, j);
}

private static <E> void wildcardSwapHelper(List<E> list, int i, int j) {
    list.set(i, list.set(j, list.get(i)));
}

์œ„ ์ฝ”๋“œ์—์„œ wildcardSwapHelper ๋ฉ”์„œ๋“œ๋Š” List<E> ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ, List<?> ํƒ€์ž…์—์„œ ๊บผ๋‚ธ ์›์†Œ์˜ ํƒ€์ž…์„ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์™ธ๋ถ€์—์„œ๋Š” List<?> ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋‚ด๋ถ€์—์„œ๋Š” List<E> ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

8) ์ด์ „ ์˜ˆ์ œ์˜ ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ ๋Œ€์‹ , Java ํ‘œ์ค€ API์ธ List.of() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•˜๋‹ค.

public static <T> List<T> pickTwo2(T a, T b, T c) {
    switch (ThreadLocalRandom.current().nextInt(3)) {
        case 0: return List.of(a, b);
        case 1: return List.of(a, c);
        case 2: return List.of(b, c);
    }
    throw new AssertionError(); // ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค.
}

@Test
public void test2() {
    List<String> pickTwo = pickTwo2("์ผ", "์ด", "์‚ผ");
    System.out.println("pickTwo = " + pickTwo);
}
  • List.of() ์‚ฌ์šฉ: List.of()๋Š” Java 9 ์ด์ƒ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‚ด๋ถ€์ ์œผ๋กœ @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์–ด ์žˆ์–ด ์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์žฅ์ : ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•จ์œผ๋กœ์จ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ณด๋‹ค ๋”์šฑ ์•ˆ์ „ํ•˜๊ณ  ์ผ๊ด€๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

โœจ ์ตœ์ข… ์ •๋ฆฌ

๊ฐ€๋ณ€์ธ์ˆ˜์™€ ์ œ๋„ค๋ฆญ์€ ์ž˜ ์–ด์šธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.

์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ์‹ค๋ฌด์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜์ง€๋งŒ, ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค. @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์™€์ผ๋“œ์นด๋“œ ํƒ€์ž…์„ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ญ์ƒ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฐฐ์—ด์— ๊ฐ’์„ ์ €์žฅํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜๊ณ , ๋ฐฐ์—ด์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ํ•ต์‹ฌ

  • ๊ฐ€๋ณ€์ธ์ˆ˜ ๊ธฐ๋Šฅ์€ ๋ฐฐ์—ด์„ ๋…ธ์ถœํ•˜์—ฌ ์ถ”์ƒํ™”๊ฐ€ ์™„๋ฒฝํ•˜์ง€ ๋ชปํ•˜๊ณ , ๋ฐฐ์—ด๊ณผ ์ œ๋„ค๋ฆญ ํƒ€์ž…์˜ ๊ทœ์น™์ด ์„œ๋กœ ๋‹ค๋ฅด๋‹ค.
  • ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํƒ€์ž… ์•ˆ์ „ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ํ—ˆ์šฉ๋œ๋‹ค.
  • ๋งค์šฐ ํŽธ๋ฆฌํ•˜์ง€๋งŒ, ์™ธ๋ถ€์— varargs ๋ฐฐ์—ด์„ ๋…ธ์ถœํ•˜๊ฑฐ๋‚˜, ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค๋ฅธ ๋ฐฐ์—ด์— ์ €์žฅํ•ด๋†“๊ณ  ๋ณ€์กฐํ•˜๋Š” ๋“ฑ์˜ ์ผ์„ ์ž์ œํ•ด์•ผ ํ•œ๋‹ค.
  • ์•ˆ์ „์ด ๋ณด์žฅ๋˜์—ˆ๋‹ค๋ฉด @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ์ด์šฉํ•˜์—ฌ ์•ˆ์ „ํ•จ์„ ํ‘œ์‹œํ•˜์ž.

๊ฒฐ๊ตญ ์“ฐ์ง€ ๋ง๋ผ๋Š” ๊ฑฐ์ž–์•„...? ์Œ ์‹ค์ œ ์ฝ”๋“œ์—์„œ๋„ ์ •์˜๋˜์–ด ์žˆ๋Š” ํด๋ž˜์Šค ๋นผ๊ณ ๋Š” ์•ˆ ์“ฐ๋Š” ๋“ฏ?

์•„๋ž˜๋Š” Collection ํด๋ž˜์Šค

์ถœ์ฒ˜