원천 타입들 Raw Types
Raw 타입은 generic 클래스 혹은 인터페이스에 타입인자가 없는 것. 예를들어 generic Box 클래스를 보자
A raw type is the name of a generic class or interface without any type arguments. For example, given the generic Box class:
public class Box<T> {
public void set(T t) { /* ... */ }
// ...
}
아래 코드를 보면 Box
To create a parameterized type of Box
Box<Integer> intBox = new Box<>();
타입인자가 생략된 경우 Box
If the actual type argument is omitted, you create a raw type of Box
Box rawBox = new Box();
결국, Box는 generic 타입 Box
Therefore, Box is the raw type of the generic type Box
Raw 타입은 JDK 5.0 이전 자바 API 클래스들은 제네릭을 지원하지 않았기 때문에(예를 들어 Collections 클래스) 레거시 코드에서 나타난다. raw 타입을 사용할 때는 반드시 generics 이전 방법(타입 캐스팅)을 하시오. 하위호환성을 위해, 타입매개변수는 raw타입을 허용하였다.
Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects. For backward compatibility, assigning a parameterized type to its raw type is allowed:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK
하지만 타입매개변수에 raw 타입을 할당하면 (컴파일러로부터) 경고를 받습니다.
But if you assign a raw type to a parameterized type, you get a warning:
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked conversion
또한 generic 타입에 정의된 generic 메서드를 호출할때에도 raw 타입을 사용하면 경고를 받습니다.
You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)
경고는 raw 타입들이 generic 타입체크를 할수 없다는 것을 보여줍니다. (컴파일 타임에 체크될 수 있는) 불안한 코드가 런타임에 붙잡히게 (컴파일 타임 체킹을 런타임으로) 딜레이 시키는 것이므로 raw 타입 사용은 피하는것이 좋을 것이다.
The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.
타입소거 섹션에서는 자바 컴파일러가 raw 타입을 사용하는 것에 대한 더 자세한 설명이 있다.
The Type Erasure section has more information on how the Java compiler uses raw types.
Unchecked Error Messages
이전에 말햇듯, generic 코드와 레거시 코드를 섞게 되면, 아래와 같은 경고 메세지를 마주칠 것이다.
As mentioned previously, when mixing legacy code with generic code, you may encounter warning messages similar to the following:
Note: Example.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
This can happen when using an older API that operates on raw types, as shown in the following example:
public class WarningDemo {
public static void main(String[] args){
Box<Integer> bi;
bi = createBox();
}
static Box createBox(){
return new Box();
}
}
“unchecked(체크되지 않음)“는 타입 안정성을 보장하기 위해 필요한 타입체크 정보가 충분치 않다는 것을 의미한다. “unchecked” 경고는 컴파일러에게 기본 설정으로는 사용하지 않는다.“unchecked” 경고를 보고 싶다면 -Xlint:unchecked옵션을 주고 다시 컴파일하면 모든 “unchecked” 경고를 볼 수 있다.
The term “unchecked” means that the compiler does not have enough type information to perform all type checks necessary to ensure type safety. The “unchecked” warning is disabled, by default, though the compiler gives a hint. To see all “unchecked” warnings, recompile with -Xlint:unchecked.
-Xlint:unchecked 옵션과 함께 예제를 다시 컴파일해보면 아래에 보이는 내용이 나타날 것이다.
Recompiling the previous example with -Xlint:unchecked reveals the following additional information:
WarningDemo.java:4: warning: [unchecked] unchecked conversion
found : Box
required: Box<java.lang.Integer>
bi = createBox();
^
1 warning
컴파일 옵션에 -Xlint:-unchecked 플래그를 사용하면 unchecked 경고를 없앨 수 있다. @SupporessWarnings(“unchecked”) 어노테이션은 unchecked 경고가 나타나지 않게 할 수 있다. @SupressWarnings 문법이 생소하면 Annotations 섹션을 보시오. 링크
To completely disable unchecked warnings, use the -Xlint:-unchecked flag. The @SuppressWarnings(“unchecked”) annotation suppresses unchecked warnings. If you are unfamiliar with the @SuppressWarnings syntax, see Annotations.
역자 첨부
$ javac WarningDemo.java
Note: WarningDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ javac -Xlint:unchecked WarningDemo.java
WarningDemo.java:7: warning: [unchecked] unchecked conversion
bi = createBox();
^
required: Box<Integer>
found: Box
1 warning