배열은 제네릭 자료형과 두 가지 중요한 차이점을 갖고 있다.
첫 째는 배열은 공변 자료형이라는 것이다. 공변자료형이란 Sub가 Super의 하위자료형이랑 Sub[]도 Super[]의 하위자료형 이라는 것이다. 반면 제네릭은 불변 자료형이다. Type1과 Type2가 있을 때 List<Type1>과 List<Type2>는 서로 상위 자료형이나 하위자료형이 될 수 없다.
먼저 위의 코드는 배열은 공변자료형이기 때문에 Long이 Object의 하위자료형이기 때문에 Long[]도 Object[]의 하위자료형이다. 따라서 컴파일단계에서 데이터를 저장하는데는 문제가 없지만, 실행단계에서 오류가 발생하게 된다. 아래의 코드는 제네릭은 불변자료형이라서 Long이 Object의 하위자료형 이더라도, List<Long>은 List<Object>의 하위자료형이 아니기때문에 컴파일단계에서 오류를 잡아내게 된다.
두 번째 차이는 배열은 실체화되는 자료형이다. 즉 배열의 각 원소의 자료형은 실행할 때 결정된다는 것이다. 반면 제네릭은 컴파일 시점에만 자료형에 대한 조건들이 적용되고, 실제 실행할 때는 자료형에 대한 정보가 사라진다. 자료형 삭제덕에, 제네릭 자료형은 제네릭을 사용하지 않고 작성된 오래된 코드와도 문제없이 연동된다.
이러한 기본적인 차이점 때문에 배열과 제네릭은 섞어 쓰기 어렵다. 예를 들어, 제네릭 자료형(List<E>)나 형인자 자료형(List<String>), 또는 형인자의 배열(E[])을 생성하는 것은 문법적으로 허용되지 않는다. 왜 허용되지 않을까? 형 안전성이 보장되지 않기 떄문이다. 문법이 허용된다면 컴파일러가 자동으로 만드는 형변환 구문(cast)들은 실행 도중에 ClassCastException 예외를 만들고 말았을 것이다.
요약
'개발서적 > 이펙티브자바' 카테고리의 다른 글
[제네릭]규칙27.가능하면 제네릭 메서드로 만들 것 (0) | 2017.05.03 |
---|---|
[제네릭]규칙26. 가능하면 제네릭 자료형으로 만들 것 (0) | 2017.04.29 |
[제네릭]규칙24. 무점검 경고를 제거하라 (0) | 2017.04.27 |
[제네릭]규칙23. 새 코드에는 무인자 제네릭 자료형을 사용하지마라. (0) | 2017.04.27 |
[클래스와 인터페이스]규칙22. 멤버 클래스는 가능하면 static으로 선언하라 (0) | 2017.04.26 |