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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

一个小栗子聊聊JAVA泛型基础

發(fā)布時(shí)間:2023/12/10 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个小栗子聊聊JAVA泛型基础 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

周五本該是愉快的,可是今天花了一個(gè)早上查問(wèn)題,為什么要花一個(gè)早上?我把原因總結(jié)為兩點(diǎn):

  • 日志信息嚴(yán)重丟失,茫茫代碼毫無(wú)頭緒。
  • 對(duì)泛型的認(rèn)識(shí)不夠,導(dǎo)致代碼出現(xiàn)了BUG。

第一個(gè)原因可以通過(guò)以后編碼謹(jǐn)慎的打日志來(lái)解決,我們今天主要來(lái)一起回顧下JAVA泛型基礎(chǔ)。

一個(gè)小栗子

先看下面一個(gè)例子,test1實(shí)例化一個(gè)List容器的時(shí)候沒(méi)有指定泛型參數(shù),那么我們可以往這個(gè)容器里面放入任何類(lèi)型的對(duì)象,這樣是不是很爽?但是當(dāng)我們從容器中取出容器中的對(duì)象的時(shí)候我們必須小心翼翼,因?yàn)槿萜髦械膶?duì)象具有運(yùn)行時(shí)的類(lèi)型信息,這意味著你不能夠?qū)⒁粋€(gè)帶有運(yùn)行時(shí)類(lèi)型信息的對(duì)象賦值給另一個(gè)類(lèi)型,否則ClassCastException

@Test public void test1() throws Exception {List list = new ArrayList();list.add("float.lu");list.add(1);String name = (String) list.get(0); int num = (Integer) list.get(1); System.out.println(String.format("name[%s], num[%s]", name, num)); }

上面的代碼沒(méi)問(wèn)題,可以很好地編譯和運(yùn)行通過(guò),問(wèn)題是我必須要事先很清楚地知道容器中的索引為0的對(duì)象是什么類(lèi)型,索引為1的對(duì)象是什么類(lèi)型,很顯然,這在實(shí)際應(yīng)用中是不切實(shí)際的,也是一種很不靠譜的做法,那么這個(gè)問(wèn)題如何解決呢?泛型。

引入泛型

為了解決這個(gè)問(wèn)題,我們引入泛型,下面代碼可以看出與上面不同的是我們?cè)趯?shí)例化容器的時(shí)候加了<String>這個(gè)東西,這個(gè)東西的學(xué)名叫做泛型參數(shù),就像普通方法帶有參數(shù)一樣,interface List<E>中的E為形式參數(shù)、而String為實(shí)參。

@Test public void test2() throws Exception { List<String> list = new ArrayList<String>(); list.add("a"); list.add(1)//1 }

引入泛型后,我們規(guī)定這個(gè)容器中只能存放類(lèi)型為字符串類(lèi)型的對(duì)象,好的,編譯器可以識(shí)別泛型并幫我們檢查編譯錯(cuò)誤,上面的代碼中1處會(huì)出現(xiàn)編譯錯(cuò)誤。注意:泛型信息僅僅存在于編譯期間,編譯器可以通過(guò)泛型信息來(lái)對(duì)代碼是否存在違規(guī)行為(編譯錯(cuò)誤)來(lái)進(jìn)行檢查,當(dāng)編譯器將代碼編譯為字節(jié)碼之后,泛型信息將不復(fù)存在,然而對(duì)象的運(yùn)行時(shí)信息仍然是有的,這就解釋了為什么會(huì)出現(xiàn)ClassCastException。

別高興太早

有了泛型我們可以讓代碼安全地通過(guò)編譯,并且我們認(rèn)為他是安全的了,嘿嘿,是否就真的安全了呢?是否就能和ClassCastException說(shuō)拜拜了呢?答案是:NO。看看下面這段代碼:

@Test public void test3() throws Exception {List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); List _list = list; List<Integer> integerList = _list; for (Integer item : integerList) { System.out.println(String.format("item[%s]", item)); } }

上面這段代碼編譯沒(méi)有問(wèn)題,我們沒(méi)有直接將泛型參數(shù)為String的容器賦值給泛型參數(shù)為Integer的容器,而是花了點(diǎn)點(diǎn)小心思,我們現(xiàn)將list賦值給_list,_list生命為可以存儲(chǔ)任何類(lèi)型,也就相當(dāng)于無(wú)特定類(lèi)型,而后我們又把_list賦值給integerList容器,integerList容器被聲明為只能存儲(chǔ)類(lèi)型為Integer的對(duì)象。悲催的是這段代碼在運(yùn)行的時(shí)候報(bào)了ClassCastException,很明顯,我們知道在迭代integerList容器中的對(duì)象的時(shí)候,這些對(duì)象是有運(yùn)行時(shí)類(lèi)型信息的,當(dāng)帶有String類(lèi)型信息的對(duì)象賦值給Integer的時(shí)候顯然就報(bào)錯(cuò)了。這一切看起來(lái)似乎沒(méi)問(wèn)題,符合邏輯,但是有一個(gè)問(wèn)題我們還沒(méi)有問(wèn):為什么會(huì)沒(méi)有編譯錯(cuò)誤?

?

泛型術(shù)語(yǔ)

在學(xué)習(xí)數(shù)學(xué)的時(shí)候我們往往會(huì)對(duì)一個(gè)證明題進(jìn)行論證,而論證之前我們手上往往會(huì)有一些不需要證明的已知定理,下面這些“定理”將被用來(lái)直接回答上一節(jié)中遺留的問(wèn)題。

  • List<E>被稱(chēng)作泛型類(lèi)型。
  • List<E>中的E被稱(chēng)為類(lèi)型變量或類(lèi)型參數(shù)。
  • List<String>被稱(chēng)為參數(shù)化類(lèi)型。
  • List<String>中的String被稱(chēng)為實(shí)際類(lèi)型參數(shù)。
  • List<E>中的<>年typeof。
  • List被稱(chēng)為原始類(lèi)型。
  • 參數(shù)化類(lèi)型可以引用一個(gè)原始類(lèi)型對(duì)象,編譯報(bào)告警告。
  • 原始類(lèi)型可以引用一個(gè)參數(shù)化類(lèi)型對(duì)象,編譯報(bào)告警告。

由上可知,List<Integer> integerList = _list;可以通過(guò)編譯。

?

看清本質(zhì)

經(jīng)過(guò)上面的一些小波折,我們了解一些關(guān)于泛型的本質(zhì):泛型是給javac編譯器使用的,javac是JAVA的編譯器,而泛型可以讓代碼在編譯期間確定類(lèi)型安全,比如我們告訴編譯器某個(gè)容器只能存儲(chǔ)某種類(lèi)型的對(duì)象,那么編譯器會(huì)為我們好好地檢查,確保類(lèi)型安全,但是安全是相對(duì)的,只要我們逃過(guò)編譯器,我們就有一百種方法讓代碼ClassCastException(比如反射)。同時(shí)編譯之后參數(shù)化類(lèi)型在運(yùn)行時(shí)沒(méi)有任何泛型信息,也就是為什么List.class和List<String>.class是同一個(gè)東西。除了參數(shù)化類(lèi)型之外,容器中的對(duì)象在運(yùn)行的時(shí)候是有類(lèi)型信息的,也就是為什么會(huì)ClassCastExcetion。關(guān)于泛型還有很多內(nèi)容,這里不做多講,文中有誤也歡迎留言討論。

轉(zhuǎn)載于:https://www.cnblogs.com/tv151579/p/7582288.html

總結(jié)

以上是生活随笔為你收集整理的一个小栗子聊聊JAVA泛型基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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