簡體   English   中英

通用類類型的參數化方法

[英]Parameterized methods in generic class type

我有一個相當簡單的問題。 我無法通過搜索找到答案。

這兩個代碼片段有區別嗎? 有什么區別?

片段1:

public class BinaryTree<T extends Comparable<? super T>> {
   ...
   public <E extends T> void add(E value) {
      ...
   }

   public <E extends T> void add(E value, Node node) {
      ...
   }
   ...
}

片段2:

public class BinaryTree<T extends Comparable<? super T>> {
   ...
   public void add(T value) {
      ...
   }

   public void add(T value, Node node) {
      ...
   }
   ...
}

片段1指定明確的是,參數必須是類型TT類型的亞型。

Fragment2指定參數必須為T類型。 但是根據我的一點知識和經驗,我認為我也可以在這里提供T的子類型。 與fragment1相同。

我查看了這兩個片段的反匯編字節碼。 確實有一個區別:

<   public <E extends T> void add(E);
---
>   public void add(T);

那只是反映了源代碼...

我只是不明白意思。 而且我也找不到一個示例應用程序,它顯示了差異。

感謝您的評論。

在這種情況下沒有區別。 讓我們以BinaryTree<Number>為例,嘗試添加一個Integer

BinaryTree<Number> numTree = new BinaryTree<>();
Integer i = 1;
numTree.add(i);

對於片段1, E可以求值為Integer ,但這在這種情況下是多余的。 Integer 是一個 Number ,您也可以為E指定Number

numTree.<Number>add(i);

因此,第二個片段與第一個片段沒有什么不同,並且由於沒有聲明不必要的類型參數而引起了混亂。


在某些情況下,附加類型參數會很有用。 想象一下由於某種原因您想要返回傳入的值:

public <E extends T> E add(E value) {
   ...
   return value;
}

public <E extends T> E add(E value, Node node) {
   ...
   return value;
}

現在,這對調用者很有用:

Integer i2 = numTree.add(i);

使用第二個代碼段是不可能的,即使您傳入IntegernumTree.add也只能返回一個Number

不, add()方法的兩個變體之間沒有區別。 Java的方法參數已經在接受的類型建立了一個上限 ,這是通過使用類型變量<E extends T>extends形式實現的相同約束。

您的類型變量不會添加任何新信息,也不會添加任何其他約束。 傳遞類型T 或任何擴展T的參數已經合法。 類型變量<E extends T>確實提供了一種再次引用實際參數類型的方法-例如,如果要確保第二個方法參數與第一個參數具有相同的類型,但是在您的情況下,您可以不使用E

暫無
暫無

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

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