Java泛型面试也能虐暴你
Java么么么——泛型
泛型是什么?
泛型就是將類型作為參數進行傳遞,當創建對象或者調用方法時才確定下具體的數據類型。并且泛型只能傳遞引用數據類型
為什么需要泛型?
在JDK5之前,對象是用Object來表示的,當要獲取具體的對象時,就得進行強制類型轉化,非常的麻煩。
比如要往一個集合Collection或者Map 中存放一個對象,存的是Object類型,例如往集合中存放了一個狗Dog對象,然后又往集合中存放了一個貓Cat類型的對象,當要從集合中get一個貓Cat對象時,就得進行類型的轉化,比較麻煩,而當用泛型之后,可以將對象的類型作為參數進行傳遞,這樣在具體要用什么對象時,就不用再進行類型轉化了。
因此總結起來,使用泛型的好處是:可以讓代碼更加簡潔,因為不用進行強制類型轉換;
讓程序更加穩健,因為使用泛型在編譯階段沒有報錯的話,在運行階段也不會報ClassCastException異常;
怎么使用泛型?
1.定義在類上的泛型 – 泛型類
將泛型定義在類上,這樣類的方法也可以使用,當具體要new對象時,用戶想要指定哪種類型,該泛型類就可以自動轉化為對應的對象類型
2.派生類的泛型
2.1子類有明確泛型的類型
子類有明確泛型的類型,在實現接口時,實現類不用定義出泛型類型
2.2.子類沒有明確泛型類型
子類沒有明確泛型的類型,在實現接口時,實現類需要定義泛型類型
3.定義在方法上的泛型 – 泛型方法
當只需要在某個方法上應用泛型時,就不用直接定義在類上,直接在方法上定義就可以了。
4.泛型類型通配符
當一個方法中要接收一個集合作為參數時,想要遍歷集合并把集合打印出來時,要想明確集合中的對象類型,
如果傳的的話,這個在集合遍歷時與這些是沒有關系的,所以Java泛型提供了類型通配符
類型通配符?可以匹配任何的Java類型。當我們使用?號通配符的時候:就只能調對象與類型無關的方法,不能調用對象與類型有關的方法。
4.1通配符上限
如果接收一個List集合,它只能操作數字類型的元素【Float、Integer、Double、Byte等數字類型都行】,如果直接使用通配符,那么該集合就不只能匹配數字了,而是任意的Java類型,因此可以設定泛型的通配符上限
例如
List<? extends Number>4.2通配符下限
類似于通配符上限,下限傳遞的類型限定只能是某種數據類型及其它的父類。
例如:
//傳遞進來的只能是Type或Type的父類<? super Type>注:大多數時候可以用泛型方法來代替泛型通配符
題目例子:
List< ? extends T > 和 List < ? super T > 之間有什么區別 ? ------ 這兩個 List 的聲明都是限定通配符的例子,List< ? extends T > 可以接受任何繼承自 T 的類型的 List,而List < ? super T > 可以接受任何 T 的父類構成的 List。
5.泛型的類型擦除
類型擦除:泛型只作用在編譯階段,用于限定集合的輸入類型,讓編譯器在源代碼級別上,即擋住向集合中插入非法數據。當編譯器編譯完帶有泛型的程序后,生成的class字節碼文件是不帶有泛型的,也就是說在運行階段不存在任何類型相關的信息。這樣使得程序運行的效率不會受影響,是確保能和 Java 5 之前的版本開發二進制類庫進行兼容。這個過程稱為類型擦除。
在泛型類被類型擦除的時候,之前泛型類中的類型參數部分如果沒有指定上限,如 < T > 則會被轉譯成普通的 Object 類型,如果指定了上限如 < T extends String > 則類型參數就被替換成類型上限。
List<String> list = new ArrayList<>();//類型被擦除了,保留的是類型的上限,String的上限就是ObjectList list1 = list;泛型可以用在哪里?-- 泛型的應用
比如在做項目時,對于Dao層,我們有很多的Dao接口類要編寫,而這些Dao接口類都有 一個共同的點就是對數據進行增刪改查,因此我們就可以定義一個抽象的Dao泛型類,在里面編寫增刪改查的方法,這樣當有具體的Dao接口去繼承它時,再去傳遞具體的數據類型即可。
例如:
抽象的Dao泛型類
public abstract class BaseDao<T> {//模擬hibernate....private Session session;private Class clazz;//哪個子類調的這個方法,得到的class就是子類處理的類型(非常重要)public BaseDao(){Class clazz = this.getClass(); //拿到的是子類ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass(); //BaseDao<Category>clazz = (Class) pt.getActualTypeArguments()[0];System.out.println(clazz);}public void add(T t){session.save(t);}public T find(String id){return (T) session.get(clazz, id);}public void update(T t){session.update(t);}public void delete(String id){T t = (T) session.get(clazz, id);session.delete(t);}}其他的具體類型的Dao接口類只要繼承這個BaseDao接口,就有進行對應類型的增刪改查操作
例如:
public class BookDao extends BaseDao<Book> { //這個類型就可以進行Book的增刪改查操作 }總結
以上是生活随笔為你收集整理的Java泛型面试也能虐暴你的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 月光满地
- 下一篇: python版本切换 for Windo