簡體   English   中英

java泛型邊界類型

[英]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)

然后存在有效的TS選擇

<T, S extends T> void work(Class<T> type, S instance)

反之亦然。

所以從理論的角度來看,它們是等價的。 但是,由於推理有限,可能會出現這樣的情況:當沒有給出類型參數時,將會編譯而另一個不會針對某些參數進行編譯。 在這種情況下,始終可以為不編譯的情況顯式指定一組有效的類型參數,以使其進行編譯。

由於它們是等價的,API應該總是更喜歡更簡單的形式,即沒有S

暫無
暫無

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

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