Item 28. 배열보다는 리스트를 사용하라

배열 vs 제네릭 리스트

배열

  • 배열은 공변(convariant)

    • 클래스 B가 A의 하위 타입이라면, B[] 또한 A[]의 하위 타입이 됨

    • 아래와 같은 코드가 문제 없이 컴파일됨

      Object[] objects = new String[3];
    • 이러한 공변성은 아래와 같은 상황에서 문제를 야기

      Object[] objects = new String[3];
      objects[0] = Long.valueOf(3); // String 배열에 Long을 저장하려 했으므로 비허용
      • 이 경우 ArrayStoreException이 발생 (즉, 런타임 에러를 야기)

  • 배열은 실체화(reify)가 가능

    • 런타임에도 자신이 담는 원소의 타입을 확인

      • String 배열인데 Long이 들어왔다? ⇒ 타입이 맞지 않으니 예외 발생

제네릭 리스트

  • 제네릭은 불공변(invariant)

    • B가 A의 하위 타입이어도 List는 List와 어떤 형변환도 불가함

    • 아래와 같은 코드는 컴파일 에러를 발생List<Object> objectList = new ArrayList<String>();

  • 제네릭은 실체가 없음제네릭의 타입 정보는 런타임에 소거되기 때문에, 런타임에는 타입 정보 소거List 객체는 실제로 어떤 타입이 들어오는지 상관하지 않음제네릭이 타입을 검사하지 않는 이유는, 런타임에 ClassCastException이 발생하지 않도록 하기 위함

제네릭 배열은 선언 불가능위와 같은 배열과 제네릭의 차이 때문에 제네릭 배열은 선언이 불가능new List<String>[] 와 같은 타입은 선언 불가만약 배열을 사용했을 때 비검사 형변환 경고가 나타난다면, 배열을 리스트로 바꾸는 것이 좋음제네릭은 해당 자료형의 데이터를 반환하므로 타입 안정성을 확보할 수 있음

Last updated