티스토리 뷰
Item53에서는 가변 인수는 신중히 사용하라 말한다
가변 인수를 사용할 때 주의점은 아래 글을 참고하자
가변 인수를 사용하면 매개변수의 개수가 정해지지 않은 상태로 클라이언트에게 매개변수를 몇 개 넘길지에 대한 책임을 넘겨
클라이언트가 필요한 만큼 넘길 수 있도록 한다는 점에서 유연한 API 설계가 가능하다
다만 varargs는 위험하다, 가변인수를 받는 메서드는 런타임에 새로운 배열이 생성되어 인수를 처리한다
어차피 사용하고 GC로 처리되겠지만 매번 새로운 배열을 생성하는 것이 찜찜할 수 있다
이에 대한 성능 최적화로 메서드 오버로딩을 통해 1 ~ 4개 정도의 인자를 받는 메서드까지 모두 만들어두고
나머지 상황에 대한 처리를 가변인수가 하도록 만들 수 있다
그러나 클라이언트가 무지막지한 개수의 인자를 넘기면 메모리가 터질 수 있다
T... args로 받는 경우 가변 인수를 넘기지 않았을 때에 대한 예외처리가 되어 있지 않다면 IndexOutOfBound가 터질수 있다
이런 경우를 막기 위해 꼼수로 첫번째 인자를 추가하여 (T arg, T... args) 형태로 받기도 한다
이 방식 역시 위에 언급한대로 클라이언트가 터트리려 마음먹으면 얼마든 터질 수 있다
다른 위험 상황으로 T... args는 T의 배열로 받아지는데 제네릭 정보는 런타임에 소거된다
컴파일 타임에만 안전성을 보장할 수 있으므로 클라이언트가 마음 먹으면 타입 안정성을 박살 낼 수 있다
밸덩의 예시를 보면 알 수 있다
배열을 사용할 수 밖에 없는 저수준의 코드가 아니라면 가변 인수 대신 컬렉션을 받는 것이 좋지 않을까 한다
이게 궁금해서 왜 collection 안 쓰고 varargs를 써야하는지에 대해 찾아봤는데 알맞은 자료를 찾지 못 했다
대부분 varargs vs array에 대한 내용이었고 컬렉션은 없었다, 요건 나중에 더 찾아봐야할 것 같다
자바 9 이후로는 List.of() 쓰거나 이전 버전은 Arrays.asList() 쓰면 Heap Pollution 같은 것은 간단하게 해결되는 문제다
List.of()도 내부적으로 가변 인수를 사용해 처리하고 클라이언트가 타입 안전성을 헤치지 못하게 Immutable 컬렉션으로 반환해준다
'Java > Effective Java' 카테고리의 다른 글
[Item55] Optional vs Null check (2) | 2022.05.14 |
---|---|
[Item54] null 멈춰 (0) | 2022.05.09 |
[Item52] 다중정의는 타입이 다르게 (0) | 2022.05.05 |
[Item51] 설계를 신중히 (0) | 2022.05.01 |
[Item50] 방어적 복사본과 불변 클래스 (0) | 2022.04.24 |