[英]Unchecked cast behavior with and without assignment to variable
為什么main中的第一行不會拋出ClassCastException,而第二行呢?
import java.util.function.Function;
class Scratch {
static <T> T getSomething(Function<Integer, T> fun) {
return (T) fun;
}
public static void main(String[] args) {
Scratch.<String>getSomething(x -> "hello");
String something = Scratch.<String>getSomething(x -> "hello");
}
}
不同之處在於,您不會在第一種情況下使用方法的結果,而是在第二種情況下使用方法的結果。
強制轉換是一個表達式 ,但它不是StatementExpression
。 這意味着你不能這樣寫:
(String) somethingReturningAString();
但你可以寫:
String aString = (String) somethingReturningAString();
在編譯時,編譯器會在需要的地方插入checkcast
指令,以及它可以在何處:
String
東西分配給一個String
變量。 因此,它會檢查強制轉換,但失敗了。 值得一提的,有一些可能是意料之外的情況下,強制轉換不是絕對必要的 ,但插入。 例如:
Scratch.<String>getSomething(x -> "hello").toString();
將失敗的ClassCastException
,因為它將轉換為:
((String) Scratch.getSomething(x -> "hello")).toString();
即使Object
有一個toString()
方法,所以它可以在沒有強制轉換的情況下調用它。
泛型只是一個編譯時檢查(讀取類型擦除 )。 所以在運行時你的getSomething()
方法看起來類似於:
static Object getSomething(Function fun) {
return fun;
}
現在你清楚地看到第一行永遠不會拋出異常
Scratch.getSomething(x -> "hello");
因為Function
是一個Object
,因此可以毫無問題地返回。
然而,第二行會拋出一個,因為這將類似於此:
String something = (String) Scratch.getSomething(x -> "hello");
Function
仍然是一個Object
因此它可以從方法返回,但它不是String
,因此,您得到ClassCastException
。
代碼編譯得很好,因為你指示編譯器你知道你在做什么。 您將在此行中收到Unchecked cast
警告:
return (T) fun;
此警告應該是編譯器向您(程序員)指示它(編譯器)無法確定該轉換是否成功的指示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.