簡體   English   中英

Java方法和泛型

[英]Java methods and generics

為什么泛型被聲明為方法的一部分? 例如,在創建使用泛型的方法時,必須在方法修飾符之后包含泛型:

public static <T, K> void delete(AbstractDao<T, K> dao)

方法的泛型部分未顯示為方法聲明的一部分。 根據java文檔,方法包含以下項目:

修改器 - 例如公共,私人和其他您將在稍后了解的內容。

返回類型 - 方法返回的值的數據類型,如果方法未返回值,則返回void。

方法名稱 - 字段名稱的規則也適用於方法名稱,但約定略有不同。

括號中的參數列表 - 以逗號分隔的輸入參數列表,前面是數據類型,括在括號中,()。 如果沒有參數,則必須使用空括號。

參考: https//docs.oracle.com/javase/tutorial/java/javaOO/methods.html

這是因為您必須單獨考慮泛型類型參數聲明用法

在沒有第一個<T,K>的方法聲明中,如下所示:

public static void delete(AbstractDao<T, K> dao)

編譯器不會知道TK應該是方法類型參數(從方法調用推斷)。 它會期望TK已經被聲明(例如導入),因為這些是泛型的用法 ,而不是聲明。

這就是為什么你需要在編譯器的修飾符之后聲明<T, K> ,告訴它TK是從方法調用中推斷出的類型參數。

當您聲明這樣的泛型類時,不會發生此問題:

public class MyClass<T> {
}

因為T在這里沒有其他含義,只能是類型參數聲明


注意:您還可以區分聲明和用法之間的區別,因為您可以在聲明期間約束類型參數,但不能在使用期間約束類型參數。 這是有效的:

public static <T extends Pony, K> void delete(AbstractDao<T, K> dao)

雖然這不是:

public static <T, K> void delete(AbstractDao<T extends Pony, K> dao)

為什么編譯器不聰明?

你可以告訴我,編譯器可能很聰明,它可以看到沒有聲明類型,推斷它應該是通用的。 但如果是這樣的話,那真是一團糟。

在大多數情況下,您的方法不是通用的。 在大多數情況下,如果已經實際定義了Something則會使用List<Something>類的參數。 想象一下,如果你只是忘記導入Something類......

編譯器將假設一個泛型類型參數,由對象擦除,你不明白為什么你不能使用你的類的方法等。它需要一些時間才能意識到什么是錯的,因為編譯器會接受這樣的聲明。

有關更權威和完整的文檔資源,請參閱Java語言規范。 特別是在這個案例的8.4節方法聲明中 ,他們明確提到了類型參數:

方法聲明可以調用的可執行代碼,將固定數量的值作為參數傳遞。

MethodDeclaration:

{MethodModifier} MethodHeader MethodBody

MethodHeader:

Result MethodDeclarator [Throws]

TypeParameters {Annotation} Result MethodDeclarator [Throws]

MethodDeclarator:

Identifier ( [FormalParameterList] ) [Dims]

來自http://math.hws.edu/javanotes/c10/s5.html “我們需要使用類型參數的名稱替換方法定義中的特定類型String,例如T.但是,如果這是只有我們改變,編譯器會認為“T”是實際類型的名稱,它會將其標記為未聲明的標識符。我們需要某種方式告訴編譯器“T”是一個類型參數。這就是什么<T>在泛型類“class Queue <T> {...”的定義中執行。對於泛型方法,<T>就在方法的返回類型的名稱之前“所以,< T>在方法名稱告訴編譯器方法簽名中的T不是實際類型,而是泛型。

泛型只是“泛型類型”的縮寫,可以表示返回類型或參數類型(如您的情況: AbstractDao<T, K> )。 並且語言的語法要求在泛型類型中指定的類型變量應該在方法的返回類型之前聲明,以便它們可以包含返回和參數類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM