반응형
배열과 제네릭 자료형의 두가지 차이점
1. 배열은 공변 자료형이다.(covariant)
· Sub가 Super의 하위 자료형이라면 Sub[]는 Super[]의 하위 자료형이다.
· 제네릭은 불변 자료형이기 때문에 List<Type1>과 List<Type2>는 상위나 하위 자료형이 아니다.
· 배열을 쓰면 실행 시 알 수 있으나, 리스트를 쓰면 컴파일 시 알 수 있다.
// 런타임 에러
Object[] objectArray = new Long[1];
objectArray[0] = "dont fit in"; // ArrayStoreException발생
// 컴파일 에러
List<Ojbect> ol = new ArrayList<Long>(); //자료형 불일치
ol.add("dont fit in");
2. 배열은 실체화 되는 자료형이다.
· 배열의 자료형은 실행시간에 결정된다.
· 반면 제네릭 자료형은 삭제를 통해 구현된다.
위와같은 차이점 때문에 배열과 제네릭은 섞어 쓰기 어렵다.
· 제네릭 자료형이나 형인자 자료형, 또는 형인자의 배열을 생성하는 것은 문법적으로 허용되지 않는다.
* 제네릭 배열 생성은 형 안전성 때문에 보장되지 않는다.
//제네릭 배열 생성이 허용되지 않는 이유
List<String>[] stringLists = new List<String>[1]; //1 - 정상동작된다면
List<Integer> intList = Arrays.asList(42); //2 - Integer리스트 초기화
Object[] objects = stringLists; //3 - 배열은 공변이므로 동작
objects[0] = intList; //4 - Object[0]에 대입
String s = stringLists[0].get(0); //5 - 배열안의 원소 꺼내는데 컴파일러는
제네릭 배열 생성 오류에 대한 가장 좋은 해결책은 List<E>를 쓰는 것이다.
// 리스트를사용하는 제네릭 버전 reduce
static <E> E reduce(List<E> list, Function<E> f, E initVal){
List<E> snapshot;
synchronized(list){
snapshot = new ArrayList<E>(list);
}
E result = initVal;
for (E e : snapshot){
result = f.apply(result, e);
return result;
}
결론
· 제네릭과 배열이 따르는 자료형 규칙은 서로 많이 다르다.
· 배열은 공변 자료형이자 실체화 가능 자료형이다.
· 제네릭은 불변 자료형이며 실행 시간에 형인자 정보는 삭제 된다. 따라서 배열은 컴파일 시간에 형 안전성을 보장하지 못하며, 제네릭은 그 반대다.
· 일반적으로 배열과 제네릭은 쉽게 혼용할 수 없다.
· 만일 배열과 제네릭을 뒤섞어 쓰다가 컴파일 오류가 생긴다면 배열을 리스트로 바꿔야 겠다는 생각을 해야한다.
반응형
'IT > Programming' 카테고리의 다른 글
<Effective Java> RULE 23 새 코드에는 무인자 제네릭 자료형을 사용하지 마라 (0) | 2023.04.27 |
---|---|
<Effective Java> RULE 24 무점검 경고(unchecked warining)을 제거하라 (0) | 2023.04.27 |
<Effective Java> RULE 26 가능하면 제네릭 자료형으로 만들 것 (0) | 2023.04.27 |
<Effective Java> RULE 27 가능하면 제네릭 메서드로 만들 것 (0) | 2023.04.27 |
<Effective Java> RULE 28 한정적 와일드카드를 써서 API 유연성을 높여라 (0) | 2023.04.27 |