中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Java泛型方法

發布時間:2022-05-20 10:36:34 來源:億速云 閱讀:340 作者:zzz 欄目:大數據

這篇“如何使用Java泛型方法”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“如何使用Java泛型方法”文章吧。

泛型方法

一般定義如下,即方法的前面加了個<T>

public class FTest {
	public <T> List<T> f(T t){...};
}

三種泛型參數推斷方式:

1、直接在f()前面加確定泛型

fTest.<Integer>f(xxx)

2、通過輸入參數確定, 下面這個推斷為Integer

int number = 0;
fTest.f(number)

3、可通過 返回值 確定

List<Integer> list = fTest.f(xxx);

Q: 下面這段代碼哪里有問題? 是toString()那里嗎?

public class A<T> {
	public static void  test(T t){
  		System.out.println(t.toString());  
  }
}

A:test是static方法, 因此無法感知A<T>實例里的T
需要改成
public static <T> void test(T t)

toString()那里沒問題,toString就是Object的方法。

泛型參數和類型消除

Q: 泛型參數T在運行時,會變成什么?
A: 統一變成Object且不包含任何類型信息。

Q: 泛型參數T可以可以使用instanceof做比較嗎?

class A<T> {
   void f(Object arg)
   if(arg instanceof T) {
	  ...
   }
}

A: 不能,編譯器會報錯。

Q: 泛型參數T可以進行new T()或者new T[]操作嗎?
A: 不能,編譯器會報錯。

如何使用Java泛型方法

Q: 能調用泛型參數對象里的方法嗎?

T.f();

A: 只能調用Object的方法。

Q: 可以用T做強制轉化嗎?

T t = (T)object;

A: 能運行, 但不會真正發生轉型, 編譯時會觸發waring警告。

新建泛型對象時的問題

先假定有2個類, 基類Parent 和子類Child

class Parent{}
class Child extends Parent{}

回答以下問題:
Q:下面這句話有問題嗎?

List<Parent> list = new ArrayList<Child>()

A:有問題,編譯就錯誤了。 List<Parent>和ArrayList<Child>并不存在父子類的關系

Q:

List<? extends Parent> list = new ArrayList<Child>();

這個list有什么特點?

A:這個list可以調用A a = list.get(), 但是不能list.add(new Parent())

  • 原因:
    list.get()所做的操作是在返回時, 把內部的<? extend Parent> 強轉成Parent, 是合理的,任何Parent的子類都可以轉成Parent
    list.add(new Parent())所做的操作是在輸入時, 把外部的A轉成內部的<? extend Parent>, 這是不合理的,因為我們不知道這個Parent對象可以轉成哪個Parent的子類。

Q:

List<? super Child> list = new ArrayList<Parent>();

這個list有什么特點?
下面誰會報錯

list.add(new Child())
list.add(new Parent())
Parent a= list.get();
Child b = list.get()

A:截圖如下:

如何使用Java泛型方法

  • Child c = list.get() 或者Parent p = list.get()所做的操作是在返回時, 把內部的<? super Child> 強轉成外部的Parent或者child, 是不合理的, 因為編譯器覺得child的父類 不一定 能轉成parent或者child,所以禁止了這種行為( 比如parent的父類是object, 但object不一定就能轉成parent或者child)。*list.add(new Child())所做的操作是在輸入時, 把外部的child或者parent轉成內部的<? super Child>, 這是合理的,因為child和parent一定能轉成child的父類。

Q:

List<?> list = new ArrayList<A>();

這個list有什么特點?

A:get和add都不行,只能做remove等無返回值無輸入A的操作。
PS: 注意,不是說不能調用get或add方法, 而是調用get或add時,不能使用A這個對象去操作。
即無法做add(A) 或者 A a = get(0)
但是可以做add(object) 或者Object o = get(0)
因為?可以轉為Object, 但是無法轉為A。

Q:下面這個代碼會報錯嗎?

   List<Fruit> fruitList = new ArrayList<>();
   fruitList.add(new Fruit());
   List<Apple> appleList = new ArrayList<>();
   appleList.add(new Apple());
   fruitList.addAll(appleList);
   System.out.println(fruitList);

A:不會報錯。會正常打印結果。

如何使用Java泛型方法

PECS原則
注意PECS原則和上面的區別!
上面之前提到的? extend或者? supert, 都是在聲明對象的時候用的。
而PECS原則是用于泛型對象的方法輸入參數!

假設有一個類定義如下:

public static class MyList<T> {
    List<T> list = new ArrayList<>();

    // 把輸入參數塞給自己,類似于生產操作
    public void pushList(List<T> t) {
        list.addAll(t);
    }

    // 把自己的內容塞給輸入參數,類似于讓輸入參數做消費。
    public void pollList(List<T> t) {
         t.addAll(list);
    }
}

則T就是泛型參數。

Q:下面代碼能正常運行嗎?

MyList<Number> myList = new MyList<>();

List<Integer> intList = new ArrayList<>();
myList.pushList(intList);

List<Object> objectList = new ArrayList<>();
myList.pollList(objectList);

A:不能正常運行, pushList和pollList都會報錯

因為編譯器檢查后,認為 List<Integer>和List<Number>不是一個東西!

Q: 如果上文要支持pushList,應該怎么修改pushList方法的定義?
A:改成這樣:

// 把輸入參數塞給自己,類似于生產操作
public void pushList(List<? extends T> t) {
    list.addAll(t);
}

即編譯器認為,List<Integer> 和List<? extend Number>是一個東西,允許!

Q: 如果要支持pollList,怎么修改定義?
A:

// 把自己的內容塞給輸入參數,類似于讓輸入參數做消費。
public void pollList(List<? super T> t) {
    t.addAll(list);
}

因為是把自己的東西塞給輸入參數, 而想要能塞進去,必須保證自己這個T,是輸入參數的子類,反過來說,輸入參數必須是T的父類,所以用super
于是編譯器認為,List<Object> 和List<? super Number>是一個東西,允許!

PECS原則出自Effective Java, 注意只是一個編程建議而已!

  • 如果有一個類A,泛型參數為T

  • 如果他一般只用于接收輸入容器List后,塞入自己內部的T容器, 則類A就叫生產者, 因此輸入參數最好定義為<? extend T>最好, 以便能接收任何T子類的容器。

  • 如果他一般只用于接收輸入容器后List, 把自己內部的T元素塞給它, 那么這個類A就叫消費者, 輸入參數最好定義為<? super T>\ 最好, 以便自己的T元素能塞給任何T元素的父類容器。

以上就是關于“如何使用Java泛型方法”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

二手房| 昭平县| 牡丹江市| 乳源| 新邵县| 荥经县| 延安市| 台东县| 马尔康县| 涟水县| 乾安县| 喀喇沁旗| 大理市| 夏津县| 禄劝| 大冶市| 尼玛县| 乌审旗| 凌云县| 白沙| 东丰县| 禹城市| 德兴市| 昆明市| 鲁甸县| 保靖县| 得荣县| 鄂州市| 偃师市| 连州市| 苍梧县| 安徽省| 澎湖县| 洪雅县| 临颍县| 六安市| 广西| 砀山县| 洛南县| 莱芜市| 花莲县|