[Effective Java] - 5장 아이템 28. 배열보다는 리스트를 사용하라

yeom yaloo·2023년 12월 20일
0

Effective Java

목록 보기
16/20
post-thumbnail

제네릭

[아이템 28. 배열보다는 리스트를 사용하라]

[핵심 정리]

  • 배열은 실체화, 공변 등의 문제가 있다.
  • 위의 문제를 제네릭의 리스트는 완벽하게 해결해준다. 그러니까 해당 문제가 발생하면 우리는 뒤도 돌아보지 말고 제네릭 리스트를 이용해 배열을 교체해주자

[배열과 리스트의 차이]

1. 공변

  • sub가 super의 하위 타입이라면 배열 sub[]는 배열 super[]의 하위 타입이다.
  • 그러나 제네릭(리스트 등)은 하위 타입도, 상위 타입도 아니다.

1-1. 런타임시 오류를 발견하는 배열

//런타임에 오류가 난다.
Object[] o = new Long[1];
o[0] = "String 값을 야무지게 넣어야지~"; //ArrayStoreException을 던진다.

List<Object> genericList = new List<Long>();
genericList.add("타입이 달라서 넣을 수 없삼");
  • 위의 코드는 모두 다 허용하지 않는 문법이다. 그러나 배열의 경우엔 런타임시에 이 문제가 드러나고 제네릭의 경우엔 컴파일 시 해당 문제를 발견한다.
  • 가능한 컴파일시에 오류를 잡아내는 것이 좋다.

2. 배열의 실체화

  • 배열이 실체화 된다는 의미는 런타임에도 자신이 담기로 한 원소의 타입을 인지하고 확인한다. 그래서 Long 타입의 배열에 String 값을 넣으려 하면 ArrayStoreException이 발생하게 된다.
  • 런타임시까지도 담아둔 원소의 데이터 타입을 인지하고 있는 배열과 달리, 제네릭의 경우엔 런타임시에는 타입이 소거되기 때문에 instanceof를 사용할 땐 로타입을 쓰는 것을 권장했다.
  • 타입의 소거는 제네릭 지원 전의 코드와 제네릭의 코드를 함께 사용할 수 있도록 해주는 매커니즘이다.
  • 그래서 타입을 끝까지 가져가는 배열의 실체화는 제네릭과 잘 어울리지 못한다.

3. 제네릭 타입, 매개변수화 타입, 타입 매개변수로 사용할 수 없는 배열

  • 배열은 제네릭 타입, 매개변수화 타입, 타입 매개변수로 사용할 수 없다.
  • List<E>[] 제네릭 배열 불가
  • new List<String>[]
  • new E[]

4. 제네릭 배열을 막아둔 이유

  • 타입이 안전하지 않기 때문이다.
  • 컴파일 시 컴파일러가 제공하는 자동 형변환에서 런타임시 ClassCastException이 발생할 수 있기 때문이다.

[배열 대신 제네릭]

  • 배열의 경우엔 형변환할 때 문제가 많다.
  • 이를 제네릭을 사용해서 해결하면 좋다.
  • 제네릭과 배열을 같이 합쳐 쓰다가 오류가 나면 가장 먼저 배열을 리스트로 대체하는 방법을 고려하자
profile
즐겁고 괴로운 개발😎

0개의 댓글