基于java中泛型的總結(jié)分析
要我直接說(shuō)出泛型是個(gè)what我還真講不出來(lái),這里先由一道問(wèn)題引入:
定義一個(gè)坐標(biāo)點(diǎn)類,要求能保存各種類型的數(shù)據(jù),如:整形,浮點(diǎn)型,和字符串類型
既然變量類型起先不確定,那么很容易想到就是用所有類型的父類,也就是Object類來(lái)代替
不廢話了,用代碼來(lái)體現(xiàn)
實(shí)例1:用Object來(lái)實(shí)現(xiàn)不確定的數(shù)據(jù)類型輸入
//這是定義的坐標(biāo)點(diǎn)類
class Point {
private Object x;
private Object y;
//用Object來(lái)表示不確定的類型
public Point(Object x, Object y) {
this.setX(x);
this.setY(y);
}
public void setX(Object x) {
this.x = x;
}
public Object getX() {
return x;
}
public void setY(Object y) {
this.y = y;
}
public Object getY() {
return y;
}
}
//測(cè)試類
public class Demo {
public static void main(String[] args) {
System.out.println("用浮點(diǎn)數(shù)表示坐標(biāo): ");
Point p = new Point(12.23,23.21);
//這里把Object類轉(zhuǎn)為Double類,然后自動(dòng)拆箱,下面兩種一樣
System.out.println("X的坐標(biāo) " + (Double)p.getX());
System.out.println("Y的坐標(biāo) " + (Double)p.getY());
System.out.println();
System.out.println("用整數(shù)表示坐標(biāo): ");
Point p2 = new Point(12, 23);
System.out.println("X的坐標(biāo) " + (Integer)p2.getX());
System.out.println("Y的坐標(biāo) " + (Integer)p2.getY());
System.out.println();
System.out.println("用字符串表示坐標(biāo): ");
Point p3 = new Point("北緯29度", "東經(jīng)113度");
System.out.println("X的坐標(biāo) " + (String)p3.getX());
System.out.println("Y的坐標(biāo) " + (String)p3.getY());
}
}
這樣就可以代入不同類型數(shù)據(jù)了,但你別忘了,此時(shí)的數(shù)據(jù)還是Object型,也就是所有類型的父類
你必須清醒的明白自己傳入的是什么類型,然后將其做向下轉(zhuǎn)型處理才能使用
雖然這樣做滿足了需求,不過(guò)卻隱含了一個(gè)不安全因素,為什么說(shuō)是隱含呢?
比如我們用new Point(12.23,"北緯29度")來(lái)構(gòu)造一個(gè)Point對(duì)象
然后都用(Double)將其向下轉(zhuǎn)型,會(huì)產(chǎn)生什么結(jié)果?
沒(méi)錯(cuò),編譯會(huì)通過(guò),但是一旦運(yùn)行則會(huì)發(fā)生類型轉(zhuǎn)換異常
要避免類轉(zhuǎn)換異常也很簡(jiǎn)單,把Object聲明換成固定類型聲明(如:String x,String y)即可,這樣編譯時(shí)就會(huì)報(bào)錯(cuò)
然后你就可以尋找出錯(cuò)的地方進(jìn)行修改
不過(guò)如此一來(lái),我們就滿足不了需求了
為了達(dá)到不存在安全隱患和代入各種數(shù)據(jù)類型的目的,那些牛人們?cè)贘DK1.5當(dāng)中引入了泛型這一概念
我們來(lái)看看如何用泛型改寫上面的代碼
實(shí)例2:泛型類
class Point<T> {
//這里用T來(lái)表示不確定的類型
private T x;
private T y;
public Point(T x, T y) {
this.setX(x);
this.setY(y);
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
}
public class Demo {
public static void main(String[] args) {
System.out.println("用浮點(diǎn)數(shù)表示坐標(biāo): ");
//用泛型改寫后,使用數(shù)據(jù)無(wú)需再做向下轉(zhuǎn)型處理
Point<Double> p = new Point<Double>(12.23,23.21);
System.out.println("X的坐標(biāo) " + p.getX());
System.out.println("Y的坐標(biāo) " + p.getY());
System.out.println();
System.out.println("用整數(shù)表示坐標(biāo): ");
Point<Integer> p2 = new Point<Integer>(12, 23);
System.out.println("X的坐標(biāo) " + p2.getX());
System.out.println("Y的坐標(biāo) " + p2.getY());
System.out.println();
System.out.println("用字符串表示坐標(biāo): ");
Point<String> p3 = new Point<String>("北緯29度", "東經(jīng)113度");
System.out.println("X的坐標(biāo) " + p3.getX());
System.out.println("Y的坐標(biāo) " + p3.getY());
}
}
使用泛型過(guò)后,可減少安全隱患的存在
如果此時(shí)我們刻意傳入不一樣的數(shù)據(jù)類型:
Point<Double> p = new Point<Double>("北緯29度",12.22);
那么,在編譯時(shí)就會(huì)報(bào)錯(cuò)
雖然定義了泛型,但如果你在構(gòu)造函數(shù)中并未使用泛型機(jī)制的話,那么它便會(huì)把數(shù)據(jù)當(dāng)作Object處理
這樣做的目的主要是為了兼容JDK1.4以前的老代碼,如
Point p = new Point(22.11,23.21);
最終運(yùn)行結(jié)果是一樣的,但在編譯時(shí)卻會(huì)提示警告信息
實(shí)例3:泛型方法
由上面的例子可以看到,一旦在構(gòu)造方法中明確對(duì)象類型,那么整個(gè)類中就將使用同一種類型
最典型的例子是運(yùn)用在集合框架里面,如:ArrayList<Integer> al = new ArrayList<Integer>();
此時(shí),al中操作的所有對(duì)象類型便都是Integer了
可是,有時(shí)候我們并不希望固定死操作的對(duì)象,而是希望更夠更加靈活的使用泛型技術(shù)
這個(gè)時(shí)候就可以嘗試泛型方法
//類名后面不再定義泛型
class Print {
//在方法中定義泛型
public <T> void print(T t) {
System.out.println(t);
}
public <E> void show(E e) {
System.out.println(e);
}
}
public class Demo {
public static void main(String[] args) {
Print p = new Print();
p.print(12);
p.print("hello");
p.show(new Integer(33));
p.show(23);
}
}
其實(shí)這樣一來(lái),與在方法中使用Object對(duì)象已經(jīng)沒(méi)有什么太大區(qū)別了
何況,JDK1.5之后加入了自動(dòng)拆裝箱功能,省去了需要向下轉(zhuǎn)型的麻煩
實(shí)例4:泛型接口
//定義一個(gè)泛型接口
interface Inter<T>
{
public void print(T t);
}
//實(shí)現(xiàn)方式一:
class InterDemo1 implements Inter<String> {
public void print(String t) {
System.out.println("print: " + t);
}
}
//實(shí)現(xiàn)方式二:
class InterDemo2<T> implements Inter<T> {
public void print(T t) {
System.out.println("print: " + t);
}
}
class Demo {
public static void main(String[] args) {
InterDemo1 id1 = new InterDemo1();
id1.print("hello");
InterDemo2<Integer> id2 = new InterDemo2<Integer>();
id2.print(new Integer(23));
}
}
實(shí)現(xiàn)泛型接口的方式有兩種,一種是在實(shí)現(xiàn)的時(shí)候指定泛型類型
另一種是依然使用泛型,在構(gòu)造的時(shí)候確定泛型類型
相關(guān)文章
java -jar設(shè)置添加啟動(dòng)參數(shù)實(shí)現(xiàn)方法
這篇文章主要介紹了java -jar設(shè)置添加啟動(dòng)參數(shù)實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02Java?OpenCV圖像處理之SIFT角點(diǎn)檢測(cè)詳解
SIFT,即尺度不變特征變換,是用于圖像處理領(lǐng)域的一種描述。這種描述具有尺度不變性,可在圖像中檢測(cè)出關(guān)鍵點(diǎn),是一種局部特征描述子。本文將詳細(xì)介紹一下Java?OpenCV圖像處理中的SIFT角點(diǎn)檢測(cè),需要的可以參考一下2022-02-02基于SSM實(shí)現(xiàn)學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于SSM實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12深入了解HttpClient的ResponseHandler接口
這篇文章主要為大家介紹了深入了解HttpClient的ResponseHandler接口,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10老生常談Java中instanceof關(guān)鍵字的理解
java 中的instanceof 運(yùn)算符是用來(lái)在運(yùn)行時(shí)指出對(duì)象是否是特定類的一個(gè)實(shí)例。這篇文章主要介紹了老生常談Java中instanceof關(guān)鍵字的理解,需要的朋友可以參考下2018-10-10Java中Optional的正確用法與爭(zhēng)議點(diǎn)詳解
這篇文章主要介紹了Java中Optional的正確用法與爭(zhēng)議點(diǎn)的相關(guān)資料,需要的朋友可以參考下2022-11-11SpringCloud?微服務(wù)數(shù)據(jù)權(quán)限控制的實(shí)現(xiàn)
這篇文章主要介紹的是權(quán)限控制的數(shù)據(jù)權(quán)限層面,意思是控制可訪問(wèn)數(shù)據(jù)資源的數(shù)量,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(45)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07