'Raw use of parameterized class 'List' 라는 경고를 보고 Raw use가 무엇인지 찾아봤는데 이펙티브 자바에 있는 내용이라 아직 초반부를 보고 있지만 해당 부분을 읽어보았다.
제네릭 타입은 일련의 매개변수화 타입(parameterized type)을 정의하는데 List<String>의 경우 원소의 타입이 String인 리스트를 뜻하는 매개변수화 타입인 것이다.
Raw Type이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말하는데 아래와 같이 원소의 타입을 정의하지 않고 List를 그대로 사용한 것이다.
List<String> listA = new ArrayList<>();
//Raw use of parameterized class 'List'
List listB = new ArrayList<>();
Raw Type은 제네릭이 도입되기 이전에 수 많은 코드들과 호환되도록 하기 위해 있는 것인데 가장 큰 문제는 타입 오류를 런타임에서야 발견할 수 있는 것이다.
제네릭을 활용하면 엉뚱한 타입의 인스턴스를 넣으려 할 때, 컴파일 오류가 발생해서 런타임 되기 전에 오류를 알아차릴 수 있다. Raw Type을 쓰면 제네릭이 주는 안전성과 표현력을 잃게 되는 것이다.
제네릭 타입을 쓰고 싶지만 실제 타입 매개변수가 무엇인지 신경 쓰고 싶지 않으면 Raw Type보다 비한정적 와일드 카드를 사용하는 것이 좋다.
예외적으로 class 리터럴에는 매개변수화 타입을 사용할 수 없기 때문에 List.class 형태의 Raw Type으로 사용해야 하며, instanceOf 연산자도 런타임시에는 제네릭 정보가 지워지기 때문에 매개변수화 타입에는 적용할 수 없어 다음과 같이 검사 형변환(checked cast)으로 사용하는 것이 좋다.
if (o instanceof Set) {
Set<?> s = (Set<?>) o;
...
}
아직 제네릭에 대한 공부가 더 필요하지만 Raw Type으로 선언 시 컴파일시에 문제점을 발견할 수 있는 제네릭의 장점을 살리지 못하고 런타임 오류가 발생할 수 있는 위험에 대해 알 수 있었다.
'Java' 카테고리의 다른 글
[Java] 추상 클래스와 인터페이스 (0) | 2022.10.04 |
---|---|
[Java] Optional 체크 주의점(orElse, orElseGet) (0) | 2022.09.30 |
[Java] HashMap put() 반환값 (null 조심) (0) | 2022.08.09 |
[Java] equals() 사용시 주의점 (NullPointerException) (0) | 2022.08.04 |
[Java] System.arraycopy() 와 Arrays.copyOf() 차이점 (JMH 벤치마킹) (0) | 2022.08.03 |