您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“java中使用泛型屏蔽類型的差異性是什么”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“java中使用泛型屏蔽類型的差異性是什么”這篇文章吧。
在C++語言中,有個很好用的模板(template)功能,可以編寫帶有參數(shù)化類型的通用版本,讓編譯器自動生成針對不同類型的具體版本。而在Java語言中,也有一個類似的功能叫泛型(generic)。在編寫類和方法的時候,一般使用的是具體的類型,而用泛型可以使類型參數(shù)化,這樣就可以編寫更通用的代碼。
許多人都認為,C++模板(template)和Java泛型(generic)兩個概念是等價的,其實實現(xiàn)機制是完全不同的。C++模板是一套宏指令集,編譯器會針對每一種類型創(chuàng)建一份模板代碼副本;Java泛型的實現(xiàn)基于"類型擦除"概念,本質上是一種進行類型限制的語法糖。
以支撐類為例,定義泛型的通用支撐類:
/** 通用支撐類 */@Getter@Setter@ToStringpublic class GenericHolder<T> { /** 通用取值 */ private T value; /** 構造函數(shù) */ public GenericHolder() {} /** 構造函數(shù) */ public GenericHolder(T value) { this.value = value; } }
定義泛型的數(shù)據(jù)提供者接口:
/** 數(shù)據(jù)提供者接口 */public interface DataProvider<T> { /** 獲取數(shù)據(jù)函數(shù) */ public T getData(); }
定義泛型的淺拷貝函數(shù):
/** 淺拷貝函數(shù) */public static <T> T shallowCopy(Object source, Class<T> clazz) throws BeansException { // 判斷源對象 if (Objects.isNull(source)) { return null; } // 新建目標對象 T target; try { target = clazz.newInstance(); } catch (Exception e) { throw new BeansException("新建類實例異常", e); } // 拷貝對象屬性 BeanUtils.copyProperties(source, target); // 返回目標對象 return target; }
泛型通配符一般是使用"?"代替具體的類型實參,可以把"?"看成所有類型的父類。當具體類型不確定的時候,可以使用泛型通配符 "?";當不需要使用類型的具體功能,只使用Object類中的功能時,可以使用泛型通配符 "?"。
/** 打印取值函數(shù) */public static void printValue(GenericHolder<?> holder) { System.out.println(holder.getValue()); }/** 主函數(shù) */public static void main(String[] args) { printValue(new GenericHolder<>(12345)); printValue(new GenericHolder<>("abcde")); }
在Java規(guī)范中,不建議使用泛型通配符"?",上面函數(shù)可以改為:
/** 打印取值函數(shù) */public static <T> void printValue(GenericHolder<T> holder) { System.out.println(holder.getValue()); }
在使用泛型的時候,我們還可以為傳入的泛型類型實參進行上下界的限制,如:類型實參只準傳入某種類型的父類或某種類型的子類。泛型上下界的聲明,必須與泛型的聲明放在一起 。
上界通配符(extends):
上界通配符為”extends”,可以接受其指定類型或其子類作為泛參。其還有一種特殊的形式,可以指定其不僅要是指定類型的子類,而且還要實現(xiàn)某些接口。例如:List<? extends A>表明這是A某個具體子類的List,保存的對象必須是A或A的子類。對于List<? extends A>列表,不能添加A或A的子類對象,只能獲取A的對象。
下界通配符(super):
下界通配符為”super”,可以接受其指定類型或其父類作為泛參。例如:List<? super A>表明這是A某個具體父類的List,保存的對象必須是A或A的超類。對于List<? super A>列表,能夠添加A或A的子類對象,但只能獲取Object的對象。
PECS(Producer Extends Consumer Super)原則:
作為生產者提供數(shù)據(jù)(往外讀取)時,適合用上界通配符(extends);
作為消費者消費數(shù)據(jù)(往里寫入)時,適合用下界通配符(super)。
在日常編碼中,比較常用的是上界通配符(extends),用于限定泛型類型的父類。例子代碼如下:
/** 數(shù)字支撐類 */@Getter@Setter@ToStringpublic class NumberHolder<T extends Number> { /** 通用取值 */ private T value; /** 構造函數(shù) */ public NumberHolder() {} /** 構造函數(shù) */ public NumberHolder(T value) { this.value = value; } }/** 打印取值函數(shù) */public static <T extends Number> void printValue(GenericHolder<T> holder) { System.out.println(holder.getValue()); }
以上是“java中使用泛型屏蔽類型的差異性是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。