[英]java generics bounds type
以下兩個簽名是否相同?
public static <T> void work(Class<T> type, T instance);
和
public static <T, S extends T> void work(Class<T> type, S instance);
不,這兩個簽名不一樣。 從Java語言規范,第8章 :
如果兩個方法具有相同的名稱和參數類型,則它們具有相同的簽名。
如果滿足以下所有條件,則兩個方法或構造函數聲明M和N具有相同的參數類型:
- 它們具有相同數量的形式參數(可能為零)
- 它們具有相同數量的類型參數 (可能為零)
...
由於您的兩種方法不共享相同數量的類型參數,因此簽名不同。
在使用隱式類型參數調用方法的實際情況中,它們可能被視為可互換。 但這只是在源級別,而不是在二進制級別。 換句話說,如果你在類Foo
有一個work()
-parameter版本的work()
並且它被類Bar
的方法調用,然后你切換到work()
的兩個類型參數版本並重新編譯Foo
,你還需要重新編譯Bar
。
@onepotato問道:
如果他們沒有相同的簽名,那么為什么當我將它們復制並粘貼到一個類Eclipse時告訴我他們有相同的方法簽名?
兩個簽名相等且兩個簽名沖突 (“覆蓋等效”)之間存在差異。 如果一個是另一個的子簽名,則兩個簽名沖突。 稍后將在同一部分對此進行說明:
如果m1是m2的子簽名或m2是m1的子簽名,則兩個方法簽名m1和m2是覆蓋等價的。
在類中聲明具有覆蓋等效簽名的兩個方法是編譯時錯誤。
方法m1的簽名是方法m2的簽名的子簽名,如果:
- m2與m1具有相同的簽名,或
- m1的簽名與m2簽名的擦除(§4.6)相同。
只看字節碼我們就可以看到它們沒有:
為了第一:
// access flags 0x9
// signature <T:Ljava/lang/Object;>(Ljava/lang/Class<TT;>;TT;)V
// declaration: void work<T>(java.lang.Class<T>, T)
public static work(Ljava/lang/Class;Ljava/lang/Object;)V
L0
LINENUMBER 86 L0
RETURN
L1
LOCALVARIABLE type Ljava/lang/Class; L0 L1 0
// signature Ljava/lang/Class<TT;>;
// declaration: java.lang.Class<T>
LOCALVARIABLE instance Ljava/lang/Object; L0 L1 1
// signature TT;
// declaration: T
MAXSTACK = 0
MAXLOCALS = 2
對於第二個:
// access flags 0x9
// signature <T:Ljava/lang/Object;S:TT;>(Ljava/lang/Class<TT;>;TS;)V
// declaration: void work<T, ST>( extends java.lang.Class<T>, S)
public static work(Ljava/lang/Class;Ljava/lang/Object;)V
L0
LINENUMBER 86 L0
RETURN
L1
LOCALVARIABLE type Ljava/lang/Class; L0 L1 0
// signature Ljava/lang/Class<TT;>;
// declaration: java.lang.Class<T>
LOCALVARIABLE instance Ljava/lang/Object; L0 L1 1
// signature TS;
// declaration: S
MAXSTACK = 0
MAXLOCALS = 2
對於任何參數集,如果存在有效的T
選擇
<T> void work(Class<T> type, T instance)
然后存在有效的T
和S
選擇
<T, S extends T> void work(Class<T> type, S instance)
反之亦然。
所以從理論的角度來看,它們是等價的。 但是,由於推理有限,可能會出現這樣的情況:當沒有給出類型參數時,將會編譯而另一個不會針對某些參數進行編譯。 在這種情況下,始終可以為不編譯的情況顯式指定一組有效的類型參數,以使其進行編譯。
由於它們是等價的,API應該總是更喜歡更簡單的形式,即沒有S
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.