Replies: 1 comment 1 reply
-
byte 코드로 설명해주시는 부분 매우 좋았습니다 !! |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
item 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라.
핵심 정리
제네릭 가변인수 배열에 값을 저장하는 것은 안전하지 않다.
@SafeVarargs
애노테이션을 사용할 수 있다.제네릭 가변인수 배열의 참조를 밖으로 노출하면 힙 오염을 전달할 수 있다.
@SafeVarages
를 사용한 메서드에 넘기는 것은 안전하다.아이템 28의 조언에 따라 가변인수를 List를 바꾼다면
@SafeVarages
애너테이션을 사용할 필요가 없다.⚓️서론
가변인수(varargs) 메서드와 제네릭은 자바 5때 함께 추가되었다.
서로 잘 어울리겠지? 라는 기대는 산산히 조각난다.
가변 인수는 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 구현 방식에 허점이 있다.
허점은 가변인수를 메서드로 호출하면 가변인수를 담기 위한 배열이 자동으로 만들어진다.
그 결과 varagrs 매개변수에 제네릭이나 매개 변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생한다.
이제 자세히 알아보자.
✅제네릭과 varargs를 혼용하면 타입 안전성이 깨진다.
🔡코드를 뜯어 보면
ClassCastException
이 발생한다.제네릭을 쓰는 큰 특징은 컴파일 타임부터 런타임까지 타입 안정성을 확보하기 위한 용도로 쓰인다.
하지만 위의 코드는 런타임의 타입 안정성이 깨지는 모습을 보여준다.
그럼 안전하게 쓰는 방법은 ??
✅제네릭 varargs 매개변수를 안전하게 사용하는 메서드
자바 7 전에는 제네릭 가변인수 메서드의 작성자가 호출자 쪽에서 발생하는 경고에 대해서 해줄 수 있는 일이 없다.
사용하기에 신경이 쓰인다.
사용자는 이 경고들을 그냥 두거나 (더 흔하게는) 호출하는 곳마다 @SuppressWarnings(”unchecked”) 애너테이션을 달아 경고를 숨겨서 사용했다.
이런 과정은 안좋은 결과( 가독성 떨어지고, 진짜 문제를 알려주는 경고마저 숨김)로 이어진다.
자바 7에서는
@SafeVarargs
애너테이션이 추가되어 제네릭 가변인수 메서드 작성자가 클라이언트 측에서 발생하는 경고를 숨길 수 있게 되었다.그렇다면 메서드가 안전한지 안한지 어떻게 알 수 있을까?
조건 1.
조건 2.
예제 코드를 통해서 알아보자.
🔡코드를 뜯어보자.
이유는 Object가 가상 추상적이기 때문에 어떤 타입이 오더라도 넣어 줄 수 있기 때문이다.
이유는 Object[] 에서 구체적인 타입인 String 으로는 타입 캐스팅은 되질 않는다. (Runtime Exception)
결과의 근본적인 문제를 살펴보면 내부적으로 만든 배열을 밖으로 노출되었기 때문이다.
자신의 제네릭 매개변수 배열의 참조를 노출했기 때문이다.
그럼 위 코드를 어떻게 안전하게 쓸 수 있을까 ?
간단히 말하자면 배열 대신 리스트를 사용하면된다.
배열 대신 리스트를 만드는방법 자세히 보려면 item28
🔡코드를 뜯어보자
List를 사용하여 타입 안정성이 보장이된다.
🔡코드를 뜯어보자
Beta Was this translation helpful? Give feedback.
All reactions