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

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

๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๋ฉ”์„œ๋“œ์— ๋„˜๊ธฐ๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.

static void test(List<String>... param) { }

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋Š” ์ œ๋„ค๋ฆญ๊ณผ ํ•จ๊ป˜ ์ž๋ฐ”5์— ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์•„์‰ฝ๊ฒŒ๋„ ์ด ๋‘˜์€ ์„œ๋กœ ์ž˜ ์–ด์šฐ๋Ÿฌ์ง€์ง€ ์•Š๋Š”๋‹ค.

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

๊ฐ€๋ณ€์ธ์ˆ˜๋Š” ๊ตฌํ˜„ ๋ฐฉ์‹์— ํ—ˆ์ ์ด ์žˆ๋‹ค.

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ ๋ฐฐ์—ด์ด ์ž๋™์œผ๋กœ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ง„๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋‚ด๋ถ€๋กœ ๊ฐ์ถฐ์•ผ ํ–ˆ์„ ์ด ๋ฐฐ์—ด์ด ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

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


๊ฑฐ์˜ ๋ชจ๋“  ์ œ๋„ค๋ฆญ๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์€ ์‹ค์ฒดํ™”๋˜์ง€ ์•Š๋Š”๋‹ค.

(item 28์—์„œ ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์€ ๋Ÿฐํƒ€์ž„์—๋Š” ์ปดํŒŒ์ผํƒ€์ž„๋ณด๋‹ค ํƒ€์ž… ๊ด€๋ จ ์ •๋ณด๋ฅผ ์ ๊ฒŒ ๋‹ด๊ณ  ์žˆ์Œ์„ ๋ฐฐ์› ๋‹ค.)

๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ๋•Œ ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์œผ๋กœ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๋ณด๋‚ธ๋‹ค.

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋„ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์‹ค์ฒดํ™” ๋ถˆ๊ฐ€ ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๋ฉด ๊ทธ ํ˜ธ์ถœ์— ๋Œ€ํ•ด์„œ๋„ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝ๊ณ ๋ฅผ ๋‚ธ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์˜ ๋ณ€์ˆ˜๊ฐ€ ํƒ€์ž…์ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ํž™ ์˜ค์—ผ์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™ ์ƒ์„ฑํ•œ ํ˜•๋ณ€ํ™˜์ด

์‹คํŒจํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ œ๋„ค๋ฆญ ํƒ€์ž… ์‹œ์Šคํ…œ์ด ์•ฝ์†ํ•œ ํƒ€์ž… ์•ˆ์ •์„ฑ์˜ ๊ทผ๊ฐ„์ด ํ”๋“ค๋ ค๋ฒ„๋ฆฐ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด์ž

static void dangerous(List<String>... stringLists) {
    Object[] objects = stringLists;
    objects[0] = List.of(42);
    String s = stringLists[0].get(0);
}

์ด ๋ฉ”์„œ๋“œ์—์„œ๋Š” ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๊ณณ์ด ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ ์‹คํ–‰ํ•ด๋ณด๋ฉด ClassCastException์„ ๋˜์ง„๋‹ค.

์™œ๋ƒํ•˜๋ฉด ๋งˆ์ง€๋ง‰ ์ค„์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ƒ์„ฑํ•œ ํ˜•๋ณ€ํ™˜์ด ์ˆจ์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด์ฒ˜๋Ÿผ ํƒ€์ž… ์•ˆ์ •์„ ์ด ์‰ฝ๊ฒŒ ๊นจ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋„ค๋ฆญ varargs ๋ฐฐ์—ด ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค.

๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์ด์œ ?

์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์„ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š”๊ฑด ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ

์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?

List<String>[] stringLists = new List<String>[10]; //์„ ์–ธ ๋ถˆ๊ฐ€

์™œ๋ƒํ•˜๋ฉด ์ œ๋„ค๋ฆญ์ด๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์˜ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋งค์„œ๋“œ๊ฐ€

์‹ค๋ฌด์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค! ๊ทธ๋ž˜์„œ ์–ธ์–ด ์„ค๊ณ„์ž๋Š” ์ด ๋ชจ์ˆœ์„ ์ˆ˜์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฟ ์ œ๊ณตํ•œ๋‹ค.

  • Arrays.asList(T... a)

  • Collections.addAll(Collection<? super T> c, T... elements)

  • EnumSet.of(E first, E... rest)

์ด ๋ฉ”์„œ๋“œ๋“ค์€ ํƒ€์ž… ์•ˆ์ „ํ•˜๊ฒŒ ์„ค๊ณ„๋˜์–ด ์žˆ๋‹ค.

@SafeVarargs

์ž๋ฐ” 7 ์ „์—๋Š” ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ์˜ ์ž‘์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ์ž ์ชฝ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ ์— ๋Œ€ํ•ด์„œ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์—†์—ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ์— ์ข€ ๊บผ๋ฆผ์น™ํ–ˆ๋‹ค.

์‚ฌ์šฉ์ž๋Š” ์ด ๊ฒฝ๊ณ ๋“ค์„ ๊ทธ๋ƒฅ ๋‘๊ฑฐ๋‚˜ ํ˜ธ์ถœํ•˜๋Š” ๊ณณ๋งˆ๋‹ค @SuppressWarnings("unchecked") ์• ๋„ˆํ…Œ์ด์…˜์„ ๋‹ฌ์•„ ๊ฒฝ๊ณ ๋ฅผ ์ˆจ๊ฒจ์•ผ ํ–ˆ๋‹ค. (item 27)

์ด๋Š” ์ง€๋ฃจํ•œ ์ž‘์—…์ด๊ณ , ๊ฐ€๋…์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๋ฉฐ, ๋•Œ๋กœ๋Š” ์ง„์งœ ๋ฌธ์ œ๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ฒฝ๊ณ ๋งˆ์ € ์ˆจ๊ธฐ๋Š” ์•ˆ ์ข‹์€ ๊ฒฐ๊ณผ๋กœ ์ด์–ด์กŒ๋‹ค.


์ž๋ฐ” 7์—์„œ๋Š” @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

@SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์€ ๋ฉ”์„œ๋“œ ์ž‘์„ฑ์ž๊ฐ€ ๊ทธ ๋ฉ”์„œ๋“œ๊ฐ€ ํƒ€์ž… ์•ˆ์ „ํ•จ์„ ๋ณด์žฅํ•˜๋Š” ์žฅ์น˜๋‹ค.

๋•๋ถ„์— ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ ์ž‘์„ฑ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ ๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ๋Š” @SafeVarargs์˜ ์•ˆ์ „ํ•จ์„ ๋ฏฟ๊ณ  ๊ทธ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด ๋”์ด์ƒ ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์•ˆ์ „ํ•œ ๋ฉ”์„œ๋“œ์—๋งŒ @SafeVarargs๋ฅผ ๋‹ฌ์ž

๋งค์„œ๋“œ๊ฐ€ ์•ˆ์ „ํ•œ ๊ฒŒ ํ™•์‹คํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ ˆ๋Œ€ @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ๋‹ฌ๋ฉด ์•ˆ๋œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ฉ”์„œ๋“œ๊ฐ€ ์•ˆ์ „ํ•œ์ง€๋Š” ์–ด๋–ป๊ฒŒ ํ™•์‹ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

๊ฐ€๋ณ€์ธ์ˆ˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋‹ด๋Š” ์ œ๋„ค๋ฆญ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง„๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ธฐ์–ตํ•˜์ž.

๋ฉ”์„œ๋“œ๊ฐ€ ์ด ๋ฐฐ์—ด์— ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๊ณ (๊ทธ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ๋ฎ์–ด์“ฐ์ง€ ์•Š๊ณ )

๊ทธ ๋ฐฐ์—ด์˜ ์ฐธ์กฐ๊ฐ€ ๋ฐ–์œผ๋กœ ๋…ธ์ถœ๋˜์ง€ ์•Š์œผ๋ฉด(์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๊ฐ€ ๋ฐฐ์—ด์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค๋ฉด)

ํƒ€์ž… ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ฌ๋ฆฌ ๋งํ•˜๋ฉด, ์ด varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์ด ํ˜ธ์ถœ์ž๋กœ๋ถ€ํ„ฐ ๊ทธ ๋ฉ”์„œ๋“œ๋กœ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์ธ์ˆ˜๋“ค์„

์ „๋‹ฌํ•˜๋Š” ์ผ๋งŒ ํ•œ๋‹ค๋ฉด(varargs์˜ ๋ชฉ์ ๋Œ€๋กœ๋งŒ ์“ฐ์ธ๋‹ค๋ฉด) ๊ทธ ๋ฉ”์„œ๋“œ๋Š” ์•ˆ์ „ํ•˜๋‹ค.


๊ทธ๋Ÿฐ๋ฐ varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์— ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๊ณ ๋„ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๊นฐ ์ˆ˜๋„ ์žˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ€๋ณ€์ธ์ˆ˜๋กœ ๋„˜์–ด์˜จ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์„ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ œ๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋‹ค.

์–ผํ• ๋ณด๋ฉด ํŽธ๋ฆฌํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ๋ณด์ด์ง€๋งŒ, ๋ณด๊ธฐ์™€ ๋‹ฌ๋ฆฌ ์œ„ํ—˜ํ•˜๋‹ค!

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

์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฐ์—ด์˜ ํƒ€์ž…์€ ์ด ๋ฉ”์„œ๋“œ์— ์ธ์ˆ˜๋ฅผ ๋„˜๊ธฐ๋Š” ์ปดํŒŒ์ผํƒ€์ž„์— ๊ฒฐ์ •๋œ๋‹ค.

๊ทธ ์‹œ์ ์—๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์ถฉ๋ถ„ํ•œ ์ •๋ณด๊ฐ€ ์ฃผ์–ด์ง€์ง€ ์•Š์•„ ํƒ€์ž…์„ ์ž˜๋ชป ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ž์‹ ์˜ varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฉด

ํž™ ์˜ค์—ผ์„ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์ชฝ์˜ ์ฝœ์Šคํƒ์œผ๋กœ๊นŒ์ง€ ์ „์ดํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ์„ ์ˆ˜ ์žˆ๋‹ค.

๊ตฌ์ฒด์ ์ธ ์˜ˆ๋ฅผ ํ†ตํ•ด ์œ„ ์œ„ํ—˜์„ ์‚ดํŽด๋ณด์ž.

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();// ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค.
} 

์ด ๋ฉ”์„œ๋“œ๋Š” ์ œ๋„ค๋ฆญ ๊ฐ€๋ณ€์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” toArray ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ์ ๋งŒ ๋นผ๋ฉด ์œ„ํ—˜ํ•˜์ง€ ์•Š๊ณ  ๊ฒฝ๊ณ ๋„ ๋‚ด์ง€ ์•Š๋Š”๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋ฅผ ๋ณธ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” toArray์— ๋„˜๊ธธ T ์ธ์Šคํ„ด์Šค 2๊ฐœ๋ฅผ ๋‹ด์„ varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

์ด ์ฝ”๋“œ๊ฐ€ ๋งŒ๋“œ๋Š” ๋ฐฐ์—ด์˜ ํƒ€์ž…์€ Object[]์ด๋‹ค.

pickTwo์— ์–ด๋–ค ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋„˜๊ธฐ๋”๋ผ๋„ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  toArray ๋ฉ”์„œ๋“œ๊ฐ€ ๋Œ๋ ค์ค€ ์ด Object[] ๋ฐฐ์—ด์ด ๊ทธ๋Œ€๋กœ pickTwo๋ฅผ ํ˜ธ์ถœํ•œ ํด๋ผ์ด์–ธํŠธ๊นŒ์ง€ ์ „๋‹ฌ๋œ๋‹ค.

์ฆ‰, pickTwo๋Š” ํ•ญ์ƒ Object[] ํƒ€์ž… ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋‹ค์Œ์€ pickTwo๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

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

์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ˆ ๋ณ„๋‹ค๋ฅธ ๊ฒฝ๊ณ  ์—†์ด ์ปดํŒŒ์ผ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์‹คํ–‰ํ•˜๋ ค ๋“ค๋ฉด ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๊ณณ์ด ๋ณด์ด์ง€ ์•Š์•„๋„ ClassCastException์„ ๋˜์ง„๋‹ค.

์™œ๋ƒํ•˜๋ฉด pickTwo์˜ ๋ฐ˜ํ™˜๊ฐ’์„ attributes์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด

String[]๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ž๋™ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Object[]๋Š” String[]์˜ ํ•˜์œ„ ํƒ€์ž…์ด ์•„๋‹ˆ๋ฏ€๋กœ ์ด ํ˜•๋ณ€ํ™˜์€ ์‹คํŒจํ•œ๋‹ค.

์ด ์‹คํŒจ๊ฐ€ ๋‹ค์†Œ ํ™ฉ๋‹นํ•˜๊ฒŒ ๋Š๊ปด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ํž™ ์˜ค์—ผ์„ ๋ฐœ์ƒ์‹œํ‚จ ์ง„์งœ ์›์ธ์ธ toArray๋กœ๋ถ€ํ„ฐ ๋‘ ๋‹จ๊ณ„๋‚˜ ๋–จ์–ด์ ธ ์žˆ๊ณ 

varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์€ ์‹ค์ œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ €์žฅ๋œ ํ›„ ๋ณ€๊ฒฝ๋œ ์ ๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


์ด ์˜ˆ๋Š” ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์— ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๊ฐ€ ์ ‘๊ทผํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋ฉด ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ƒ๊ธฐ์‹œํ‚จ๋‹ค.

๋‹จ, ์˜ˆ์™ธ๊ฐ€ ๋‘ ๊ฐ€์ง€ ์žˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ, @SafeVarargs๊ฐ€ ์„ ์–ธ๋œ ๋˜ ๋‹ค๋ฅธ varargs ๋ฉ”์„œ๋“œ์— ๋„˜๊ธด๋Š” ๊ฒƒ์€ ์•ˆ์ „ํ•˜๋‹ค.

๋‘ ๋ฒˆ์งธ, ํ•ด๋‹น ๋ฐฐ์—ด ๋‚ด์šฉ์˜ ์ผ๋ถ€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ๋งŒ ํ•˜๋Š”(varargs๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”) ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ์— ๋„˜๊ธฐ๋Š” ๊ฒƒ๋„ ์•ˆ์ „ํ•˜๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ์ „ํ˜•์ ์ธ ์˜ˆ๋‹ค.

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

flatten ๋ฉ”์„œ๋“œ๋Š” ์ž„์˜ ๊ฐœ์ˆ˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๊ณ  ๋ฐ›์€ ์ˆœ์„œ๋Œ€๋กœ ๊ทธ ์•ˆ์˜ ๋ชจ๋“  ์›์†Œ๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ์˜ฎ๊ฒจ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ด ๋ฉ”์„œ๋“œ์—๋Š” @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์ด ๋‹ฌ๋ ค ์žˆ์œผ๋‹ˆ ์„ ์–ธํ•˜๋Š” ์ชฝ๊ณผ ์‚ฌ์šฉํ•˜๋Š” ์ชฝ ๋ชจ๋‘์—์„œ ๊ฒฝ๊ณ ๋ฅผ ๋‚ด์ง€ ์•Š๋Š”๋‹ค.


@SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ๋ฅผ ์ •ํ•˜๋Š” ๊ทœ์น™์€ ๊ฐ„๋‹จํ•˜๋‹ค.

์ œ๋„ค๋ฆญ์ด๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™” ํƒ€์ž…์˜ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— @SafeVarargs๋ฅผ ๋‹ฌ์ž.

๊ทธ๋ž˜์•ผ ์‚ฌ์šฉ์ž๋ฅผ ํ—ท๊ฐˆ๋ฆฌ๊ฒŒ ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ๊ฒฝ๊ณ ๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ง์€ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ varargs ๋ฉ”์„œ๋“œ๋Š” ์ ˆ๋Œ€ ์ž‘์„ฑํ•˜์ง€ ๋ง์•ผ์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๊ธฐ๋„ ํ•˜๋‹ค.

์ž์‹ ์ด ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ ์ค‘ ์ œ๋„ค๋ฆญ varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ

ํž™ ์˜ค์—ผ ๊ฒฝ๊ณ ๊ฐ€ ๋œจ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ ๋ฉ”์„œ๋“œ๊ฐ€ ์ง„์งœ ์•ˆ์ „ํ•œ์ง€ ์ ๊ฒ€ํ•˜์ž.

์ •๋ฆฌํ•˜์ž๋ฉด, ๋‹ค์Œ ๋‘ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ์ œ๋„ค๋ฆญ varargs ๋ฉ”์„œ๋“œ๋Š” ์•ˆ์ „ํ•˜๋‹ค.

  • varargs ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด์— ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ๊ทธ ๋ฐฐ์—ด(ํ˜น์€ ๋ณต์ œ๋ณธ)์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ์— ๋…ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.

@SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์€ ์žฌ์ •์˜ํ•  ์ˆ˜ ์—†๋Š” ๋ฉ”์„œ๋“œ์—๋งŒ ๋‹ฌ์•„์•ผ ํ•œ๋‹ค.
์žฌ์ •์˜ํ•œ ๋ฉ”์„œ๋“œ๋„ ์•ˆ์ „ํ• ์ง€๋Š” ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ž๋ฐ” 8์—์„œ ์ด ์• ๋„ˆํ…Œ์ด์…˜์€ ์˜ค์ง ์ •์  ๋ฉ”์„œ๋“œ์™€ final ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ์—๋งŒ
๋ถ™์ผ ์ˆ˜ ์žˆ๊ณ , ์ž๋ฐ” 9๋ถ€ํ„ฐ๋Š” private ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ์—๋„ ํ—ˆ์šฉ๋œ๋‹ค.

@SafeVarargs ๋Œ€์‹  List ์‚ฌ์šฉํ•˜๊ธฐ

@SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์ด ์œ ์ผํ•œ ์ •๋‹ต์€ ์•„๋‹ˆ๋‹ค.

item 28์˜ ์กฐ์–ธ์„ ๋”ฐ๋ผ (์‹ค์ฒด๋Š” ๋ฐฐ์—ด์ธ) varargs ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ List ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”๊ฟ€ ์ˆ˜๋„ ์žˆ๋‹ค.

์ด ๋ฐฉ์‹์„ ์•ž์„œ์˜ flatten ๋ฉ”์„œ๋“œ์— ์ ์šฉํ•˜๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ ์„ ์–ธ๋งŒ ์ˆ˜์ •ํ–ˆ์Œ์— ์ฃผ๋ชฉํ•˜์ž.

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

์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์ธ List.of๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ด ๋ฉ”์„œ๋“œ์— ์ž„์˜ ๊ฐœ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” List.of์— @SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

List<Integer> flatList = flatten(List.of(List.of(1, 2), List.of(3, 4, 5), List.of(6,7)));

์ด ๋ฐฉ์‹์˜ ์žฅ์ ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ด ๋ฉ”์„œ๋“œ์˜ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฐ ์žˆ๋‹ค.

@SafeVarargs ์• ๋„ˆํ…Œ์ด์…˜์„ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ๋‹ฌ์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ ์‹ค์ˆ˜๋กœ ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•  ๊ฑฑ์ •๋„ ์—†๋‹ค.

๋‹จ์ ์ด๋ผ๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ์‚ด์ง ์ง€์ €๋ถ„ํ•ด์ง€๊ณ  ์†๋„๊ฐ€ ์กฐ๊ธˆ ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ •๋„๋‹ค.


๋˜ํ•œ ์ด ๋ฐฉ์‹์€ varargs ๋ฉ”์„œ๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์—์„œ๋„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

static <T> List<T> pickTwo(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();
}

๊ธฐ์กด toArray์˜ List ๋ฒ„์ „์ด ๋ฐ”๋กœ List.of๋กœ, ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฐจ์›์—์„œ ์ œ๊ณตํ•˜๋‹ˆ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š”๋„ ์—†๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

public static void main(String[] args) {
    List<String> attributes = pickTwo("์ข‹์€", "๋น ๋ฅธ", "์ €๋ ดํ•œ");
    System.out.println(attributes);
}

๊ฒฐ๊ณผ ์ฝ”๋“œ๋Š” ๋ฐฐ์—ด ์—†์ด ์ œ๋„ค๋ฆญ๋งŒ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ํƒ€์ž… ์•ˆ์ „ํ•˜๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ