이 방법의 체인 호출
System.out.println(t.second.getClass().getSimpleName());
컴파일러 효과적으로이 확장 : t.second
는 제네릭 형식임을 발생하는 경우, 지금
TypeOfTSecond tmpTSecond = t.second;
Class<?> clazzTmp = tmp.getClass();
String nameTmp = clazzTmp.getSimpleName();
System.out.println(nameTmp);
, 컴파일러는 삽입합니다 유형에 캐스트하면 t.second
이됩니다 :
Bar tmpTSecond = (Bar) t.second;
Bar
특정 기능에 액세스하지 않으므로 ClassCastException
이 표시됩니다.
이것을 설명하기 위해, 여기에서 바이트 코드이다 스택으로 푸시된다
t.second
8은
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method Test.f:()LTuple;
3: astore_1
4: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
7: aload_1
8: getfield #4 // Field Tuple.second:Ljava/lang/Object;
11: checkcast #5 // class Bar
14: invokevirtual #6 // Method java/lang/Object.getClass:()Ljava/lang/Class;
17: invokevirtual #7 // Method java/lang/Class.getSimpleName:()Ljava/lang/String;
20: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: return
라인; 11 번 행은 Bar
에 대한 캐스트가 발생하는 곳입니다.test.f()
선언 할 때
이 약 때문에 사용되는 원료 종류의 제공이가 올바르게 다음
static Tuple<String, Integer> f(){return new Tuple<>("test", 8);}
이 선으로 선언 된 경우
static Tuple f(){return new Tuple("test", 8);}
을
Tuple<String, Bar> t = Test.f();
은 컴파일되지 않습니다. 그러나 원시 타입을 사용하면 컴파일러의 타입 검사가 불가능하므로 이와 같은 런타임 오류는 방지 될 수 없습니다.
주요 테이크 아웃 강의는 never use raw types입니다.
2 차 레슨은 컴파일러 (또는 IDE) 경고에주의를 기울입니다.
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
및 그 플래그를 사용하여 컴파일 할 때 :이 코드를 컴파일, 나는 들었다
Main.java:19: warning: [unchecked] unchecked call to Tuple(K,V) as a member of the raw type Tuple
return new Tuple("test", 8);
^
where K,V are type-variables:
K extends Object declared in class Tuple
V extends Object declared in class Tuple
Main.java:26: warning: [unchecked] unchecked conversion
Tuple<String, Bar> t = Test.f();
^
required: Tuple<String,Bar>
found: Tuple
2 warnings
나의 이해가 자바에서 작동하지 않습니다이다. 귀하의 제네릭이 유형을 부여받지 못했습니다, 그들은 제네릭입니다. 이것은 당신이'public final K'을 먼저 가지고 있다면 그것은 작동 할 것이고 그것은 String을 반환 할 것입니다. –
'Test.f()'는 원시 타입을 반환합니다. 이 오류는 원시 형식을 사용하지 않아도 쉽게 포착 할 수 있습니다. 'Test.f()'의 반환 유형은 반환되는 값과 일치하도록'Tuple'로 정의되어야합니다. 그러면'Tuple t = Test.f()'에 컴파일 오류가 발생합니다. 유형 안전은 강력한 기능입니다. –
"스레드의 예외"메인 "java.lang.ClassCastException : java.lang.Integer를 Bar에 캐스트 할 수 없습니다"라는 오류 메시지를 게시해야합니다. 이제는 훨씬 더 명확 해지고 있습니다 ... – alfasin