隔着超薄肉丝进入小说_男女刺激性视频大片_女教师的诱波多野结衣_一级欧美过瘾大片

當前位置: 首頁 / 技術(shù)干貨 / 正文
民哥帶你快速精通java泛型(五)

2022-10-24

泛型 類型 定義

  第五關(guān) 泛型的離奇失蹤

  小伙們看到這個標題,可能會大吃一驚,我們不是定義好泛型了嗎,那么泛型還會突然離奇失蹤啊。

  我可以很負責的告訴小伙們: 泛型確實會消失!

  1. 泛型的擦除機制(泛型消失)

好程序員

  我們定義的泛型類,泛型方法,只是編譯時:規(guī)范類型參數(shù)的傳遞,然而在編譯成class文件后,運行代碼時,這時泛型就消失了。

  原因就是:

  在JAVA的虛擬機中并不存在泛型,泛型只是為了完善java體系,增加程序員編程的便捷性以及安全性而創(chuàng)建的一種機制,在JAVA虛擬機中對應(yīng)泛型的都是確定的類型,在編寫泛型代碼后,java虛擬機中會把這些泛型參數(shù)類型都擦除,用相應(yīng)的確定類型來代替,代替的這一動作叫做類型擦除,而用于替代的類型稱為原始類型,在類型擦除過程中,一般使用第一個限定的類型來替換,若無限定,則使用Object.

  下面我們測試一下:

  //1.在Demo.java類中: 定義一個泛型的集合

  Listlist = new ArrayList();

  list.add("hello");

  list.add("java");

  //2.在編譯后的Demo.class文件中,通過反編譯查看:泛型消失了

  List list = new ArrayList();

  list.add("hello");

  list.add("java");

  2.泛型的擦除補償

  正如我們看到的,我們在代碼運行時,泛型就消失了,那么如果我們在運行代碼時需要確切的知道泛型的具體類型該怎么辦呢?特別是使用new T(),或者使用instanceof, 因為這兩類操作要知道確切的類型。

  我們可以通過泛型擦除后的補償來滿足我們的需求,一般我們會采用java中的設(shè)計模式來解決這個問題。

  方式一:簡單工廠 (最簡單)

  在此方法中,將類型作為參數(shù),以一個萬能的工廠類(其中有一個返回具體類型類的實例的泛型方法)用類的

  newInstance()方法返回參數(shù)化類型的實例,如下所示:

/**
* 定義泛型T
* @param <T>
*/
public class GenericDemo9<T> {
//1.定義泛型變量: t
private T t;
//2.定義方法:獲取t
public T getInstance(Class<T> clz){
try {
this.t = clz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return this.t;
}
//3.測試:
public static void main(String[] args) {
GenericDemo9<Date> gd = new GenericDemo9<Date>();
Date date = gd.getInstance(Date.class);
}

}

  缺點:

  因為class的newInstance()是利用無參構(gòu)造方法創(chuàng)建對象的,如果該泛型類沒有無參構(gòu)造方法,就會報錯

  方式二:工廠方法(最靈活)

  與簡單工廠相比,工廠方法更靈活,同時來解決了簡單工廠中沒有無參構(gòu)造方法,不能創(chuàng)建對象的問題。

  如下所示:

//步驟一: 定義工廠接口
/**
* 定義一個泛型接口
* @param <T>
*/
public interface GenericFactory<T> {
T create();
}
//步驟二:定義具體創(chuàng)建對象的工廠
/**
* 定義生產(chǎn)汽車的工廠
*/
class CarFactory implements GenericFactory<Car>{
//1.定義汽車的名稱
private String name;
//2. 定義汽車對象
private Car car;

public CarFactory() {
}

public CarFactory(String name) {
this.name = name;
}

@Override
public Car create() {
if(name==null){//沒有汽車名稱:表示使用無參數(shù)構(gòu)造
this.car = new Car();
}else{//有汽車名稱:表示使用有參數(shù)構(gòu)造
this.car = new Car(this.name);
}
return car;
}
//3.測試
public static void main(String[] args) {
GenericFactory<Car> gf = new CarFactory();
Car car = gf.create();//使用無參構(gòu)造創(chuàng)建對象
GenericFactory<Car> gf2 = new CarFactory("奔馳S500");
Car car2 = gf2.create();//使用有參構(gòu)造創(chuàng)建對象

}
}
//步驟三:定義對象的類
//定義一個汽車類
class Car{
private String name;
public Car() {
}
public Car(String name) {
this.name = name;
}
}

  缺點:代碼實現(xiàn)起來麻煩

  優(yōu)點:創(chuàng)建對象的方式更加靈活,使用有參和無參構(gòu)造都能創(chuàng)建對象。

  模板方法(最簡捷)與工廠方法不同的地方在于:用模板類(抽象類)來控制整個實例化過程的流程,本質(zhì)就是用模板類控制對象的創(chuàng)建過程,具體創(chuàng)建對象的實現(xiàn)由模板類的子類去實現(xiàn),只不過在模板類中需要用工廠方法。

  如下所示:

//1.創(chuàng)建模板類
public abstract class GenericTemplate<T> {
//1.定義泛型變量
private T t;
//2.定義抽象方法
public abstract T create();
}
//2.創(chuàng)建模板類的生成者(實現(xiàn)類)
class CarCreator extends GenericTemplate<Car> {
//1.定義工廠對象:引入工廠方法
private CarFactory cf ;

public CarCreator() {
this.cf = new CarFactory();
}

public CarCreator(String carName) {
this.cf = new CarFactory(carName);
}
//2.重寫模板類的方法
@Override
public Car create() {
return cf.create();
}
}

  優(yōu)點:

  方式最簡捷,因為直接調(diào)用具體的生成類即可,我們創(chuàng)建對象時,并看不到模板類的出現(xiàn)。

  闖關(guān)練習(xí)

  請描述 代碼在運行過程中 泛型在擦除后,具體表示為什么類型?(單選)

  A: Class類型

  B: T類型

  C: Object類型

  D: Type類型

  答案:C

  解析:

  在代碼運行過程中,泛型會被擦除(也就是泛型會消失),這時泛型的類型通通都會表示為Object類型。

  因為定義泛型時,可以指定任意類型,比如List<String>,Set<Number>,所以在泛型擦除后,只有Object類型可以表示任意類型。

好程序員公眾號

  • · 剖析行業(yè)發(fā)展趨勢
  • · 匯聚企業(yè)項目源碼

好程序員開班動態(tài)

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數(shù)據(jù)+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發(fā) <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數(shù)據(jù)分析 <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發(fā) <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓(xùn)IT培訓(xùn)
在線咨詢
IT培訓(xùn)IT培訓(xùn)
試聽
IT培訓(xùn)IT培訓(xùn)
入學(xué)教程
IT培訓(xùn)IT培訓(xùn)
立即報名
IT培訓(xùn)

Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號