배열 vs 리스트 무엇을 써야하는가

학습 계기

미션을 진행하면서 배열과 리스트를 아무 생각 없이 섞어서 썼는데, 배열과 리스트의 차이에 대해서 공부해보라는 리뷰를 받았다..!

1. 공변과 불공변

배열은 공변이다.

공변이란? 함께 변한다는 뜻이다.
예를 들어 Sub가 Super의 하위 타입이라면, 배열 Sub[]는 배열 Super[]의 하위타입이 된다.

제네릭은 불공변이다. 리스트는 제네릭을 사용하기 때문에 또한 불공변이다.
불공변이란? 공변의 반대 개념이다. Sub가 Super의 하위 타입이라도

List<Sub>는 List<Super>의 하위 자료형이 될 수 없다.

2. 그래서 공변과 불공변이 어쨌다는 걸까?

배열과 리스트가 가진 공변과 불공변이라는 성질은 오류가 발생하는 시점을 다르게 한다.

(1) 배열

Object[] objectArray = new Long[1];
array[0] = "문자열";

배열은 공변이라고 했다. 그러면 첫줄에서 Long은 Object의 하위 자료형이므로 Long[]도 Object[]의 하위 자료형이 되고, 컴파일 단계에서 별 문제 없이 넘어가게 된다.
그러면 오류가 난다는 것을 런타임때가 되어서야 알게 된다.

(2) 리스트

List<Object> objectList = new ArrayList<Long>();
objectList.add("문자열");

반면 제네릭 타입은 불공변이기 때문에 첫줄에서 컴파일 에러를 발생시킨다.

3. 실체화와 소거

(1) 배열
배열은 런타임에 타입이 실체화 된다.

Object[] objectArray = new Long[1];

런타임에 ObjectArray의 타입이 Long 타입으로 바뀌게 되는 것이다.
그러면 배열은 런타임일 때 타입이 안전하지만, 컴파일 할 때는 안전하지 않을 수 있다.

(2) 리스트
리스트는 런타임때에 타입이 소거된다.

List<Integer> list = new ArrayList<Integer>();
->
List list = new ArrayList();

리스트는 컴파일 할 때 타입을 확인하고 런타임에 소거하기 때문에 컴파일 할 때는 타입이 안전하지만 런타임에는 안전하지 않을 수 있다.

4. 따라서 리스트를 씁시다

따라서 리스트를 쓰면 런타임에 오류를 발견하는 일 없이, 컴파일 때 오류를 발견할 수 있다. 또한 실체화와 소거의 특성때문에 두 타입을 섞어 쓸 경우는 타입의 안정성을 보장해주지 못한다. 그러므로 되도록 리스트로 통일하여 쓰도록 하자!

좋은 웹페이지 즐겨찾기