작성
·
364
0
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
아이템 28 마지막 요약에 제네릭은 불공변
이고 타입 정보가 소거된다. 그 결과 배열은 런타임에는 타입 안전하지만 컴파일 타임에는 그렇지 않다. 제네릭은 반대다. 라고 적혀있는데
배열이 런타임에 타입 안전하다는게 이해가 잘 안됩니다.
Object[] objectArray = new Long[1];
/* ArrayStoreException 발생 */
objectArray[0] = "타입이 달라 넣을 수 없음"; //ArrayStoreExcpetion
위 코드 처럼 공변되면서 런타임에 에러가 나는데 저장 했을때 저장 시점에 에러를 반환하면 타입 안전하다고 하는건가요?
public class Chooser<T> {
private final T[] choiceArray;
public Chooser(Collection choices) {
choiceArray = (T[]) choices.toArray();
}
public T choose() {
return choiceArray[0];
}
public static void main(String[] args) {
Collection<Integer> choices = new ArrayList<>();
choices.add(1);
choices.add(2);
choices.add(3);
Chooser<String> chooser = new Chooser<>(choices);
System.out.println(chooser.choose()); //ClassCastException
}
}
제네릭은 저장 시점에는 잘못된 형식의 데이터가 들어갔는지 런타임에 검사 할 수 없기 때문에 런타임 시점에 안전하지 않다고 하는건가요?
답변 1
0
안녕하세요 exem.tr3 님, 인프런 AI 인턴이에요.
배열은 런타임에 타입 안전하지 않은 것은 맞습니다. 위의 예시에서 Object[] objectArray = new Long[1];
와 같이 배열을 생성하면, 컴파일 시에는 타입 체크가 이루어지지 않기 때문에 Long 배열에 String을 저장하려고 하면 ArrayStoreException
이 발생합니다. 이와 같은 경우에는 런타임에 에러가 발생하여 타입 안전하지 않다고 할 수 있습니다.
제네릭은 저장 시점에 잘못된 형식의 데이터가 들어갔는지 런타임에는 검사 할 수 없기 때문에 런타임 시에는 타입 안전하지 않다고 할 수 있습니다. 예를 들어, Chooser<String> chooser = new Chooser<>(choices);
에서 choices
에는 Integer
타입의 요소가 들어있지만, Chooser 객체를 생성할 때는 String
타입으로 지정하였기 때문에 ClassCastException
이 발생합니다.
이는 제네릭은 컴파일 시에 타입 체크를 수행하고 런타임에는 제네릭 타입을 소거하여 Object 타입으로 취급하기 때문에 발생하는 문제입니다. 저장 시에 형식이 유효한지 검사하지 않기 때문에 런타임에 타입에 관련된 오류가 나타날 수 있습니다.
감사합니다.