제네릭 : 컬렉션이 담을 수 있는 타입을 컴파일러에게 알려주기에 컴파일러가 스스로 형변환 코드를 추가할 수 있으며, 다른 타입의 객체를 넣으려는 시도를 차단하여 안전하고 명확한 프로그램을 만들 수 있다.
제네릭 타입 : 제네릭 클래스와 제네릭 인터페이스를 통틀어 부르는 말이며 클래스와 인터페이스 선언에 타입 매개 변수를 사용하면 이를 제네릭 클래스, 제네릭 인터페이스라 한다.
로타입은 사용하지 말라
로타입 : 제네릭 타입에서 매개변수를 전혀 사용하지 않는 것을 말한다.
로 타입을 사용하면 제네릭이 주는 안전성과 표현력을 버리게 되는 것이며 이 타입은 호환성을 위해 만들어 놓은 것이기에 사용하지 않아야 한다. 와일드 카드와 비교 했을 시에도 와일드 카드는 null이외에는 어떤 원소도 넣을 수 없게 되며 안전하다.
예외적으로 첫번째는 class 리터럴에는 로타입을 사용해야 하며, 두번째는 런타임 시 제네릭 타입의 정보가 지워지므로instanceof 연산자는 비한정적 와일드카드 타입이와의 매개변수와 타입에 적용할수 없ㅇ 로타입을 쓰는것이 좋다.
비검사 경고를 제거하라
비검사 경고를 무시하지 않으며 타입 안전하다고 확신이 된다면 @SuprressWarnings("uncheck") 어노테이션을 달아 경고를 숨기며 가능한한 가장 좁은 범위에 적용하는 것이 좋다. 또한 이러한 경우에는 주석을 남겨주는 것이 좋다.
배열보다는 리스트를 사용하라
배열과 제네릭 타입의 차이 두가지
1) 배열은 공변(함께 변한다)이다. 제네릭은 불공변이다.
2) 배열은실체화 된다.
배열은 런타임시에도 자신이 담기로 한 원소의 타입을 인지하고 확인하는 반면 제네릭은 타입정보가 런타임시에 하위호환성을 위해 제거된다.
제네릭 타입안에 배열을 넣게 되면 런타임시 타입이 제거되기에 에러가 발생한다. 이러한 이유로 제네릭 배열이 생성되지 않도록 되어있다.
E,List<E>,List<String> 같은 타입을 실체화 불가 타입이라 하며 실체화될 수 있는 타입은 List<?>같은 비 한정적 와일드 카드 타입 뿐이다.
만약 제네릭배열 생성을 하려면 2가지 방법이 있다. 안전하지 않은 방법인 Object 배열을 생성한 뒤 제네릭 배열로 하거나 push 메서드를 통해 배열에 저장하는 원소 타입은 항상 E이기에 비검사 형변환은 안전하다.
이왕이면 제네릭 타입으로 만들어라
클라이언트에서 직접 형변환하는 타입보다 제네릭 타입이 더 안전하고 쓰기 변하나 새로운 타입 설계시에는 형변환 없더라도 사용할 수 있도록 만드는 것이 좋다. 이러한 경우 주로 제네릭 타입으로 만들어야한다. 기존 타입중에 제네릭이 필요한것은 변경 시키는게 좋다. 기존 클라이언트에는 영향을 주지 않기 때문이다.
'IT > Java' 카테고리의 다른 글
이펙티브 자바 6장 - enum (0) | 2019.12.12 |
---|---|
이펙티브 자바 5장 - 제네릭 2 (0) | 2019.12.05 |
이펙티브 자바 4장 -2 (0) | 2019.12.02 |
이펙티브 자바 4장 - 1 (0) | 2019.11.27 |
이펙티브 자바 3장 (0) | 2019.11.26 |
댓글