91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

怎么使用Java泛型

發布時間:2021-07-05 16:39:59 來源:億速云 閱讀:195 作者:chen 欄目:編程語言

本篇內容介紹了“怎么使用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

衡南县| 邻水| 甘孜| 清远市| 河北省| 临邑县| 花莲县| 福州市| 绥阳县| 邵阳县| 资溪县| 金溪县| 北辰区| 称多县| 荣昌县| 新野县| 和林格尔县| 乐平市| 清水县| 定日县| 临武县| 五常市| 崇州市| 吉林市| 封开县| 海原县| 固镇县| 岳池县| 平山县| 连城县| 宜宾县| 阿克苏市| 林西县| 竹溪县| 南华县| 出国| 青冈县| 海安县| 通州市| 辽阳市| 灵寿县|