stack을 이용한 알고리즘 문제를 풀면서 발생한 일이다.
Stack클래스가 제네릭 타입임을 잊어버리고 타입 파리미터를 생략한 채로 풀게 되었는데, IDE에서 경고메시지를 보내긴 했지만 컴파일하고 실행하는 데는 문제가 없었다.
실행결과가 정상적으로 나오고 제출결과도 정답으로 나오게 되니 제네릭 타입의 클래스를 사용할 때 타입 파라미터 없이 사용하면 발생하는 문제가 무엇인지 궁금해졌고 이를 주제로 포스팅하게 되었다.
다음은 문제의 소스 코드와 경고메시지이다.
Stack st = new Stack();
boolean flag;
for (int i = 0; i < tc; i++) {
st.clear();
flag = false;
String line = br.readLine();
for (int j = 0; j < line.length(); j++) {
if (line.charAt(j) == '(') {
st.push('(');


Stack 인스턴스 생성 시 오류메시지를 보면 parameterized class를 raw하게 사용 중이라고 하며,
메서드 사용 시엔 raw type Stack클래스의 멤버인 push(E) 메서드에 대해 확인되지 않은 호출이라는 문구가 뜬다.
Raw Type이란?
자바 튜토리얼에서 말하는 raw type이란, 어떤 타입의 인자가 없는 제네릭 클래스 또는 인터페이스이다.
즉, 제네릭 타입의 클래스의 인스턴스 생성 시 파라미터 타입을 생략하게 되면 제네릭 클래스의 raw type을 만들 수 있다는 것이다. 이는 위 코드에서 Stack클래스의 인스턴스를 생성할 때 아무런 타입도 지정해주지 않은 것의 결과와 같다.
그렇다면 실행 시 문제가 없음에도 어떤 점이 문제이길래 경고메시지가 발생하는지 알아보자.
우선 제네릭 JDK5.0 이후에 생긴 개념이다. 이 때, 이전 버전과의 호환성을 위해 parameterized type을 raw type에 할당할 수 있도록 만든 것이다.
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK
그러나 raw type을 parameterized type에 할당하게 된다면, 경고 메시지가 발생하도록 되어있다.
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked conversion
또한 제네릭 클래스의 메서드를 raw type으로 호출한다면, 경고 메시지를 확인할 수 있다.
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)
내 케이스는 제네릭 클래스의 메서드를 raw type으로 호출하려했기 때문에 경고메시지가 발생한 것이다.
Raw type사용 시 제네릭 타입 정보가 전부 지워진 것처럼 동작하는데, 이는 이전 버전의 자바 코드와 호환하도록 하기 위함이다.
그대로 사용한다면 예기치 못한 오류 발생이 있을 수 있기 때문에 사용하지 않는 것이 좋을 것으로 보인다.
결론
제네릭이 없던 시절 코드와 호환을 위해 raw type이 존재할 수 있도록 만든 것이다. 제네릭 클래스를 raw type으로 사용해도 실행에 문제는 없으나, 정적 타입 언어라는 자바의 강점을 이용하기 위해선 지양하는 게 좋겠다.
참고
https://dahye-jeong.gitbook.io/java/java/effective_java/2021-05-19-generic-dont-use-raw-type https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html
https://docs.oracle.com/javase/specs/jls/se11/html/jls-4.html#d5e3546
'Language > Java' 카테고리의 다른 글
| Arrays.fill()에 참조타입을 매개변수로 전달하면? (0) | 2023.11.25 |
|---|---|
| 메서드 내에서 포장객체의 값을 변경한다면? (0) | 2023.04.25 |
| Java Garbage Collector의 수집 대상이 되기 위해 참조만 끊으면 되는 걸까? (0) | 2023.03.31 |
| 자바의 배열 크기를 바꿀 수 있을까? (0) | 2023.03.26 |
| Java 메서드 인자 전달 메커니즘 (0) | 2023.03.07 |