티스토리 뷰
개발자라면 응당 '이왕이면 다홍치마' 대신 '이왕이면 제네릭이다'라고 말해야 한다
왜 제네릭인가? 런타임에 터질 ClassCastException을 컴파일 시점에 에러로 띄워주기 때문이다
일반 클래스를 type-safe 하도록 제네릭 클래스를 만들려면 타입 매개변수를 주면 된다, Stack -> Stack<E>
단 이 클래스 내에서 배열을 사용한다면 컴파일 에러나 비검사 형 변환 경고가 뜨는데
이를 막기 위한 방법으로 두 가지가 있다
1. 주어진 타입으로 배열을 만드려고 할 때 Object[]로 만들고 그 후에 타입을 사용해 명시적인 형 변환을 때려준다
단 컴파일러는 런타임에 해당 라인이 안전함을 보장할 수 없기 때문에 개발자가 안전함을 확실하게 알 때만 사용해야 한다
이를 무시하면 런타임에 터질 에러를 막아준다는 제네릭을 사용하는 의미가 없어진다
아래 코드를 난사하면 결과가 참혹할 수 있다
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
2. 내부에서 사용하는 배열의 타입 자체를 Object로 바꿔버리고 사용할 때마다 E로 명시적 형 변환을 때리고 사용 한다
단 E는 실체화되지 않으므로 컴파일러는 런타임에 발생할 형 변환이 안전함을 보장할 수 없다
E result = (E) elements[--size];
첫 번째 방식이 가독성도 좋고 코드도 간결해 더 인기 있다고 한다
앞선 아이템에서 배열보다 리스트를 사용하라 했는데 리스트를 사용하면 저런 경고가 뜨지도 않는다
배열보다 리스트를 쓰라고 했으면서 여기서는 배열을 쓰고 앉아있네, 왜 이랬다 저랬다 하는가?
현실적인 이유로 자신이 만든 클래스에서 제네릭과 배열을 비벼 먹어야 할 수도 있기 때문이다
아무래도 성능 상의 이유가 제일 클 것이고 그 외에는 잘 모르겠다
ArrayList 같은 기본 구현체 놈들은 자바가 기본적으로 제공하는 최소한의 라이브러리만 사용하면서
만들어야 하기 때문에 기본 제공되는 배열을 사용할 수밖에 없다고 한다
대다수의 나와 같은 개발자는 기본 구현체를 만들 일은 없을 것이고 따라서 성능 상의 이유로 쓰는 일 밖에 없다
다만 웹 개발에서의 성능 저하는 배열을 쓰냐 리스트를 쓰냐 보다 더 영향을 끼치는 요소들이 차고 넘쳤다
대표적으로 네트워크 I/O, DB 커넥션, 외부 API 연동 등등
가독성과 이해하기 쉬운 코드를 위해서는 앞선 아이템의 조언을 따라 배열보다 리스트를 사용하자
정말 필요한 상황이 온다면 아이템 28에서 언급한 커스텀 제네릭 배열 클래스를 만들고 이용하는 것도 좋다
그것도 싫다면 컴파일 에러와 비검사 경고에 몇 번 맞다 보면 내성이 생기니 경험만이 답이겠다
아이템 끝 부분에는 DelayQueue <E extends Delayed>를 보여주며 한정적 타입 매개변수의 시작을 알렸다
와일드카드, 한정적 & 비한정적 매개 변수 등을 공부해가면서 중급은 오바고, 자바 초중급 개발자로 나아 가보자
'Java > Effective Java' 카테고리의 다른 글
[Item31] 한정적 와일드카드 뭐시기?? (0) | 2022.03.10 |
---|---|
[Item30] 따봉 제네릭스 (0) | 2022.03.09 |
[Item28] 배열 : 제네릭 = 공변 : 불공변 (0) | 2022.03.07 |
[Item27] @SuppressWarnings 알고 쓰자 (0) | 2022.03.06 |
[Item26] 타입으로 안전하게, 유연하게 (0) | 2022.03.04 |