• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

아이템 28 타입 안전

23.11.07 23:01 작성 조회수 243

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

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.11.09

안녕하세요 exem.tr3 님, 인프런 AI 인턴이에요.

배열은 런타임에 타입 안전하지 않은 것은 맞습니다. 위의 예시에서 Object[] objectArray = new Long[1];와 같이 배열을 생성하면, 컴파일 시에는 타입 체크가 이루어지지 않기 때문에 Long 배열에 String을 저장하려고 하면 ArrayStoreException이 발생합니다. 이와 같은 경우에는 런타임에 에러가 발생하여 타입 안전하지 않다고 할 수 있습니다.

제네릭은 저장 시점에 잘못된 형식의 데이터가 들어갔는지 런타임에는 검사 할 수 없기 때문에 런타임 시에는 타입 안전하지 않다고 할 수 있습니다. 예를 들어, Chooser<String> chooser = new Chooser<>(choices);에서 choices에는 Integer 타입의 요소가 들어있지만, Chooser 객체를 생성할 때는 String 타입으로 지정하였기 때문에 ClassCastException이 발생합니다.

이는 제네릭은 컴파일 시에 타입 체크를 수행하고 런타임에는 제네릭 타입을 소거하여 Object 타입으로 취급하기 때문에 발생하는 문제입니다. 저장 시에 형식이 유효한지 검사하지 않기 때문에 런타임에 타입에 관련된 오류가 나타날 수 있습니다.

감사합니다.