[英]Why is it `<T>Type` as return type in Java Generics and not `Type<T>`?
[英]Java generics type binding. Why isn't this compiling?
鑒於此通用 function:
<T> List<T> function() { return null; }
為什么會這樣編譯
List<String> l = function();
雖然這不?
List<String> l = (List<String>) function();
因為當你做這樣的演員時:
(List<String>) function()
編譯器無法推斷function()
調用的類型參數,而是將T
綁定到Object
。
而在
List<String> l = function();
它可以推斷T
的正確類型。
請注意,如果您通過顯式提供類型來規避類型推斷的工作,則可以強制轉換:
import java.util.List;
class Test {
public static <T> List<T> function() { return null; }
public static void main(String[] args) {
List<String> l = (List<String>) Test.<String>function();
// ^^^^^^^^^^^^^
}
}
我不知道泛型參數的確切類型推斷規則。 但是,它們在JLS 第 15.12.2.7 節中指定。
看起來類型推斷發生在嘗試強制轉換之后(由編譯器)。
表達式的類型由表達式的左側確定,在嘗試強制轉換時尚未“解析”。 並且轉換本身失敗,因為對於尚未推斷的類型,(方法調用的)結果是List<Object>
類型
JLS 的第15.12.2.7節指出類型推斷最后發生。
第一個使用類型推斷,使用分配結果的變量的類型。
在第二個中,調用的結果沒有分配給任何東西(在轉換完成之前),因此返回最通用的類型( List<Object>
),並且List<Object>
不能轉換為List<String>
。
這是因為 javac 需要推斷 T,但 T 沒有出現在參數類型中。
static<T> T foo(){ .. }
foo(); // T=?
只有在 2 種情況下,javac 可以從上下文中推斷出 T
String s = foo(); // #1: assignment
String bar(){
return foo(); // #2: return
在其他情況下,javac 不會,並且 T 被簡單地推斷為 Object
List<String>
不擴展List<Object>
。 所以你不能施放它。
您可以通過以下方式指定 T
List<String> l = this.<String>function();
那是因為編譯器無法推斷方法function()
的參數化類型,因此它將T
綁定到Object
。 您不能將List<Object>
轉換為List<String>
。
這個問題並不准確。
List<String> m = (List<String>)function();
產生警告“類型安全:從 Object 到 List 的未經檢查的轉換”這是正確的,因為對泛型類型的所有轉換都是不安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.