日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java泛型 例子_关于 Java 泛型的一些有趣的例子

發(fā)布時間:2024/4/11 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java泛型 例子_关于 Java 泛型的一些有趣的例子 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

有以下的代碼:

1 try{2 ArrayList lstA = new ArrayList();3 ArrayList lstB = new ArrayList();4

5 //ArrayList c = (ArrayList)lstA;

6

7 Object d =lstA;8 ArrayList e = (ArrayList)d;9 System.out.println("e.toString=" +e.toString());10

11 List f =lstA;12 System.out.println("f.toString=" +f.toString());13

14 if (lstA.getClass() ==lstB.getClass()) {15 System.out.println("lstA.class == lstB.class");16 }else{17 System.out.println("lstA.class != lstB.class");18 }19

20 String[] g = {"","2"};21 Object[] h =(Object[])g;22 System.out.println("h.toString=" +h.toString());23 } catch(Exception ex) {24 System.out.println("cast error!--" +ex.getMessage());25 }

運行以上代碼,估計會輸出什么?會產(chǎn)生異常嗎?

實際上,這些代碼都能正常運行。

先看看被注釋掉的第 5 行:

ArrayList c = (ArrayList)lstA;

這行會產(chǎn)生編譯錯誤,所以被注釋掉了。可是換一種方式卻可以通過編譯器的檢查,也就是接下來的7-9行:

Object d =lstA;

ArrayList e = (ArrayList)d;

System.out.println("e.toString=" + e.toString());

這幾行代碼不光是騙過編譯器,也能夠正常運行。

繼續(xù)看接下來的 11-12 行:

List f =lstA;

System.out.println("f.toString=" + f.toString());

與前面 7-9 行的有所不同的是,前面是對“類型參數(shù)”做了轉(zhuǎn)換,而此處是類型本身變了,即將 ArrayList 轉(zhuǎn)為其超類接口 List ,這能行嗎?

運行便知!OK,執(zhí)行通過!

繼續(xù)看看接下來的 14-18 行:

if (lstA.getClass() ==lstB.getClass()) {

System.out.println("lstA.class == lstB.class");

}else{

System.out.println("lstA.class != lstB.class");

}

猜猜這里輸出的結(jié)果是什么?

答案是:

"lstA.class == lstB.class"

為什么呢?難道 lstA 和 listB 是同一個類型,可是他們明明一個是 ArrayList,一個是ArrayList 。

原來這就是泛型的障眼法。

與 C# 的泛型不同,java 的泛型實際上更像是個語法上的東西,在運行時是沒有“泛型”的存在的,運行時 lstA 和 lstB 的類型都是 ArrayList (或者說等同 ArrayList)。

我們再看看最后的 20-22 行:

String[] g = {"","2"};

Object[] h=(Object[])g;

System.out.println("h.toString=" + h.toString());

這和前面的 11 行類似,對于數(shù)組同樣也行得通。當然這跟泛型沒什么關(guān)系,這種稱為“協(xié)變”,只是形式上與一些泛型的操作類似,所以放在一起比照。

以上全部代碼在我本機運行的輸出結(jié)果如下:

e.toString=[]

f.toString=[]

lstA.class == lstB.class

h.toString=[Ljava.lang.String;@e09713

再看看另外的一個例子:

1 public static voidmain(String[] args) {2 try{3 testCaster1(SQLException.class);4 } catch(SQLException e) {5 System.out.println(String.format("SQLException=[%s]--%s", e.getClass().getName(), e.getMessage()));6 } catch(Exception e) {7 System.out.println(String.format("Exception=[%s]--%s", e.getClass().getName(), e.getMessage()));8 }9

10 try{11 testCaster2(SQLException.class);12 } catch(SQLException e) {13 System.out.println(String.format("SQLException=[%s]--%s", e.getClass().getName(), e.getMessage()));14 } catch(Exception e) {15 System.out.println(String.format("Exception=[%s]--%s", e.getClass().getName(), e.getMessage()));16 }17 }18

19

20 private static void testCaster1(Class clazz) throwsE{21 try{22 throw new SQLException("測試拋出的SQL錯誤。");23 } catch(Throwable e) {24 throw(E)e;25 }26 }27 private static void testCaster2(Class clazz) throwsE{28 try{29 throw new IOException("測試拋出的IO錯誤。");30 } catch(Throwable e) {31 throw(E)e;32 }33 }

兩個泛型方法 testCaster1 和 testCaster2 的邏輯是一樣,用泛型 E 定義了 throws 拋出的異常類型,同時在內(nèi)部捕捉 Throwable 并將其轉(zhuǎn)換為聲明的泛型參數(shù)返回。

等等!!

細心的你是不是發(fā)現(xiàn)了什么不對勁的地方?...

是的,第 24 行和 31 行,明顯異常類型 E 是泛型,調(diào)用者指定的具體類型是不確定的,而這兩個方法一個拋出 SQLException,一個拋出 IOException,

那接下來的轉(zhuǎn)換要引發(fā) ClassCastException 了吧?

不過答案是否定的!它們運行得很好。

看 main 方法中的 2-8 行,調(diào)用 testCaster1 拋出的 SQLException,最終被 catch(SQLException e) 捕捉到。

再看接下來的 10-16 行,調(diào)用 testCaster2 拋出的 IOException,最終被 catch(Exception e) 捕捉到。

在 testCaster2 的內(nèi)部拋出的 IOException 似乎并沒有按照調(diào)用者指定的泛型參數(shù) SQLException 做強制轉(zhuǎn)換,因為并沒有?ClassCastException 發(fā)生。

哈哈,這又是泛型的障眼法!

全部輸出結(jié)果如下:

SQLException=[java.sql.SQLException]--測試拋出的SQL錯誤。

Exception=[java.io.IOException]--測試拋出的IO錯誤。

總結(jié)

以上是生活随笔為你收集整理的java泛型 例子_关于 Java 泛型的一些有趣的例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。