程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 淺談Java泛型中的extends和super關鍵字

淺談Java泛型中的extends和super關鍵字

編輯:JAVA編程入門知識

  泛型是在Java 1.5中被加入了,這裡不討論泛型的細節問題,這個在Thinking in Java第四版中講的非常清楚,這裡要講的是super和extends關鍵字,以及在使用這兩個關鍵字的時候為什麼會不同的限制。 
  首先,我們定義兩個類,A和B,並且假設B繼承自A。

package com.wms.test;

import java.util.ArrayList;
import java.util.List;

public class Generic {  
    public static void main(String[] args){  
          List<? extends A> list1 = new ArrayList<A>(); 
//          list1.add(new A()); //錯誤,編譯器無法確定List所持有的類型,所以無法安全的向其中添加對象
          A a = list1.get(0);
          List<? extends A> list2 = new ArrayList<B>();  
          List<? super B> list3 = new ArrayList<B>(); 
          list3.add(new B());
          //想要正確,必須向下轉型,但是向下轉型是不安全的,非常容易出錯
//          B b = list3.get(0); //編譯器無法確定get返回的對象類型是B,還是B的父類或 Object.
          List<? super B> list4 = new ArrayList<A>();  
       } 
}  

class A{}
class B extends A{}

  從上面這段創建List的代碼我們就更加容易理解super和extends關鍵字的含義了。首先要說明的一點是,Java強制在創建對象的時候必須給類型參數制定具體的類型,不能使用通配符,也就是說new ArrayList<? extends A>(),new ArrayList<?>()這種形式的初始化語句是不允許的。 

  從上面main函數的第一行和第二行,我們可以理解extends的含義,在創建ArrayList的時候,我們可以指定A或者B作為具體的類型。也就是,如果<? extends X>,那麼在創建實例的時候,我們就可以用X或者擴展自X的類為泛型參數來作為具體的類型,也可以理解為給"?"號指定具體類型,這就是extends 的含義。 

  同樣的,第三行和第四行就說明,如果<? super X>,那麼在創建實例的時候,我們可以指定X或者X的任何的超類來作為泛型參數的具體類型。 

  當我們使用List<? extends X>這種形式的時候,調用List的add方法會導致編譯失敗,因為我們在創建具體實例的時候,可能是使用了X也可能使用了X的子類,而這個信息編譯器是沒有辦法知道的,同時,對於ArrayList<T>來說,只能放一種類型的對象。這就是問題的本質。而對於get方法來說,由於我們是通過X或者X的子類來創建實例的,而用超類來引用子類在Java中是合法的,所以,通過get方法能夠拿到一個X類型的引用,當然這個引用可以指向X也可以指向X的任何子類。 

    而當我們使用List<? super X>這種形式的時候,調用List的get方法會失敗。因為我們在創建實例的時候,可能用了X也可能是X的某一個超類,那麼當調用get的時候,編譯器是無法准確知曉的。而調用add方法正好相反,由於我們使用X或者X的超類來創建的實例,那麼向這個List中加入X或者X的子類肯定是沒有問題的, 因為超類的引用是可以指向子類的。 

    最後還有一點,這兩個關鍵字的出現都是因為Java中的泛型沒有協變特性的導致的。

小結

extends 可用於的返回類型限定,不能用於參數類型限定。
super 可用於參數類型限定,不能用於返回類型限定。
>帶有super超類型限定的通配符可以向泛型對象中寫入,帶有extends子類型限定的通配符可以向泛型對象讀取。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved