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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java中已定义类型car_Java 8 习惯用语(8):Java 知道您的类型

發(fā)布時(shí)間:2025/3/8 java 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中已定义类型car_Java 8 习惯用语(8):Java 知道您的类型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java?8

是第一個(gè)支持類型推斷的 Java 版本,而且它僅對 lambda 表達(dá)式支持此功能。在 lambda

表達(dá)式中使用類型推斷具有強(qiáng)大的作用,它將幫助您做好準(zhǔn)備以應(yīng)對未來的 Java

版本,在今后的版本中還會將類型推斷用于變量等更多可能。這里的訣竅在于恰當(dāng)?shù)孛麉?shù),相信 Java 編譯器會推斷出剩余的信息。

大多數(shù)時(shí)候,編譯器完全能夠推斷類型。在它無法推斷出來的時(shí)候,就會報(bào)錯(cuò)。

了解 lambda 表達(dá)式中的類型推斷的工作原理,至少查看一個(gè)無法推斷類型的示例。即使如此,也有解決辦法。

顯式類型和冗余

假設(shè)您詢問某個(gè)人“您叫什么名字?”,他會回答“我名叫約翰”。這種情況經(jīng)常發(fā)生,但簡單地說“約翰”會更高效。您需要的只是一個(gè)名稱,所以該句子的剩余部分都是多余的。

不幸的是,我們總是在代碼中做這類多余的事情。Java 開發(fā)人員可以使用 forEach 迭代并輸出某個(gè)范圍內(nèi)的每個(gè)值的雙倍值,如下所示:IntStream.rangeClosed(1,?5)

.forEach((int?number)?->?System.out.println(number?*?2));

rangeClosed 方法生成一個(gè)從 1 到 5 的 int 值流。lambda 表達(dá)式的唯一職責(zé)就是接收一個(gè)名為 number 的 int 參數(shù),使用PrintStream 的 println 方法輸出該值的雙倍值。從語法上講,該 lambda 表達(dá)式?jīng)]有錯(cuò),但類型細(xì)節(jié)有些冗余。

Java 8 中的類型推斷

當(dāng)您從某個(gè)數(shù)字范圍中提取一個(gè)值時(shí),編譯器知道該值的類型為 int。不需要在代碼中顯式聲明該值,盡管這是目前為止的約定。

在 Java 8 中,我們可以丟棄 lambda 表達(dá)式中的類型,如下所示:IntStream.rangeClosed(1,?5)

.forEach((number)?->?System.out.println(number?*?2));

由于

Java 是靜態(tài)類型語言,它需要在編譯時(shí)知道所有對象和變量的類型。在 lambda 表達(dá)式的參數(shù)列表中省略類型并不會讓 Java

更接近動(dòng)態(tài)類型語言。但是,添加適當(dāng)?shù)念愋屯茢喙δ軙?Java 更接近其他靜態(tài)類型語言,比如 Scala 或 Haskell。

信任編譯器

如果您在 lambda 表達(dá)式的一個(gè)參數(shù)中省略類型,Java 需要通過上下文細(xì)節(jié)來推斷該類型。

返回到上一個(gè)示例,當(dāng)我們在 IntStream 上調(diào)用 forEach 時(shí),編譯器會查找該方法來確定它采用的參數(shù)。IntStream 的 forEach 方法期望使用函數(shù)接口 IntConsumer,該接口的抽象方法 accept 采用了一個(gè) int 類型的參數(shù)并返回 void。

如果在參數(shù)列表中指定了該類型,編譯器將會確認(rèn)該類型符合預(yù)期。

如果省略該類型,編譯器會推斷出預(yù)期的類型 —在本例中為 int。

無論是您提供類型還是編譯器推斷出該類型,Java 都會在編譯時(shí)知道 lambda 表達(dá)式參數(shù)的類型。要測試這種情況,可以在 lambda 表達(dá)式中引入一個(gè)錯(cuò)誤,同時(shí)省略參數(shù)的類型:IntStream.rangeClosed(1,?5)

.forEach((number)?->?System.out.println(number.length()?*?2));

編譯此代碼時(shí),Java 編譯器會返回以下錯(cuò)誤:Sample.java:7:?error:?int?cannot?be?dereferenced

.forEach((number)?->?System.out.println(number.length()?*?2));

^1?error

編譯器知道名為 number 的參數(shù)的類型。它報(bào)錯(cuò)是因?yàn)樗鼰o法使用點(diǎn)運(yùn)算符解除對某個(gè) int 類型的變量的引用。可以對對象執(zhí)行此操作,但不能對 int 變量這么做。

類型推斷的好處

在 lambda 表達(dá)式中省略類型有兩個(gè)主要好處:鍵入的內(nèi)容更少。無需輸入類型信息,因?yàn)榫幾g器自己能輕松確定該類型。

代碼雜質(zhì)更少 —(number) 比 (int number) 簡單得多。

此外,一般來講,如果我們僅有一個(gè)參數(shù),省略類型意味著也可以省略 (),如下所示:IntStream.rangeClosed(1,?5)

.forEach(number?->?System.out.println(number?*?2));

請注意,您將需要為采用多個(gè)參數(shù)的 lambda 表達(dá)式添加括號。

類型推斷和可讀性

lambda 表達(dá)式中的類型推斷違背了 Java 中的常規(guī)做法,在常規(guī)做法中,會指定每個(gè)變量和參數(shù)的類型。盡管一些開發(fā)人員辯稱 Java 指定類型的約定讓代碼變得更可讀、更容易理解,但我認(rèn)為這種偏好反映出一種習(xí)慣而不是必要性。

以一個(gè)包含一系列轉(zhuǎn)換的函數(shù)管道為例:List?result?=

cars.stream()

.map((Car?c)?->?c.getRegistration())

.map((String?s)?->?DMVRecords.getOwner(s))

.map((Person?o)?->?o.getName())

.map((String?s)?->?s.toUpperCase())

.collect(toList());

在這里,我們首先提供了一組 Car 實(shí)例和相關(guān)的注冊信息。我們獲取每輛車的車主和車主姓名,并將該姓名轉(zhuǎn)換為大寫。最后,將結(jié)果放入一個(gè)列表中。

這段代碼中的每個(gè) lambda 表達(dá)式都為其參數(shù)指定了一個(gè)類型,但我們?yōu)閰?shù)使用了單字母變量名。這在 Java 中很常見。但這種做法不合適,因?yàn)樗鼇G棄了特定于域的上下文。

我們可以做得比這更好。讓我們看看使用更強(qiáng)大的參數(shù)名重寫代碼后發(fā)生的情況:List?result?=

cars.stream()

.map((Car?car)?->?car.getRegistration())

.map((String?registration)?->?DMVRecords.getOwner(registration))

.map((Person?owner)?->?owner.getName())

.map((String?name)?->?name.toUpperCase())

.collect(toList());

這些參數(shù)名包含了特定于域的信息。我們沒有使用 s 來表示 String,而是指定了特定于域的細(xì)節(jié),比如 registration 和name。類似地,我們沒有使用 p 或 o,而是使用 owner 表明 Person 不只是一個(gè)人,還是這輛車的車主。

這個(gè)示例中的每個(gè) lambda 表達(dá)式都比它所取代的表達(dá)式更好。在讀取 lambda 表達(dá)式(例如 (Person owner) -> owner.getName())時(shí),我們知道我們獲得了車主的姓名,而不只是隨便某個(gè)人的姓名。

命名參數(shù)

Scala 和 TypeScript 等一些語言更加重視參數(shù)名而不是類型。在 Scala 中,我們在定義類型之前定義參數(shù),例如通過編寫:def?getOwner(registration:?String)

而不是:def?getOwner(String?registration)

類型和參數(shù)名都很有用,但在 Scala 中,參數(shù)名更重要一些。我們用 Java 編寫 lambda 表達(dá)式時(shí),也可以考慮這一想法。請注意我們在 Java 中的車輛注冊示例中丟棄類型細(xì)節(jié)和括號時(shí)發(fā)生的情況:List?result?=

cars.stream()

.map(car?->?car.getRegistration())

.map(registration?->?DMVRecords.getOwner(registration))

.map(owner?->?owner.getName())

.map(name?->?name.toUpperCase())

.collect(toList());

因?yàn)槲覀兲砑恿嗣枋鲂缘膮?shù)名,所以我們沒有丟失太多上下文,而且顯式類型(現(xiàn)在是冗余內(nèi)容)已悄然消失。結(jié)果是我們獲得了更干凈、更樸實(shí)的代碼。

類型推斷的局限性

盡管使用類型推斷可以提高效率和可讀性,但這種技術(shù)并不適用于所有場合。在某些情況下,完全無法使用類型推斷。幸運(yùn)的是,您可以依靠 Java 編譯器來獲知何時(shí)出現(xiàn)這種情況。

我們首先看一個(gè)測試編譯器并獲得成功的示例,然后看一個(gè)測試失敗的示例。最重要的是,在兩種情況下,都能夠相信編譯器會按期望方式工作。

擴(kuò)展類型推斷

在我們的第一個(gè)示例中,假設(shè)我們想創(chuàng)建一個(gè) Comparator 來比較 Car 實(shí)例。我們首先需要一個(gè) Car 類:class?Car?{

public?String?getRegistration()?{?return?null;?}}

接下來,我們將創(chuàng)建一個(gè) Comparator,以便基于 Car 實(shí)例的注冊信息對它們進(jìn)行比較:public?static?Comparator?createComparator()?{

return?comparing((Car?car)?->?car.getRegistration());}

用作 comparing 方法的參數(shù)的 lambda 表達(dá)式在其參數(shù)列表中包含了類型信息。我們知道 Java 編譯器非常擅長類型推斷,那么讓我們看看在省略參數(shù)類型的情況下會發(fā)生什么,如下所示:public?static?Comparator?createComparator()?{

return?comparing(car?->?car.getRegistration());}

comparing 方法采用了 1 個(gè)參數(shù)。它期望使用 Function super T, ? extends U> 并返回 Comparator。因?yàn)?comparing是 Comparator 上的一個(gè)靜態(tài)方法,所以編譯器目前沒有關(guān)于 T 或 U 可能是什么的線索。

為了解決此問題,編譯器稍微擴(kuò)展了推斷范圍,將范圍擴(kuò)大到傳遞給 comparing 方法的參數(shù)之外。它觀察我們是如何處理調(diào)用comparing 的結(jié)果的。根據(jù)此信息,編譯器確定我們僅返回該結(jié)果。接下來,它看到由 comparing 返回的 Comparator 又作為 Comparator 由 createComparator 返回 。

注意了!編譯器現(xiàn)在已明白我們的意圖:它推斷應(yīng)該將 T 綁定到 Car。根據(jù)此信息,它知道 lambda 表達(dá)式中的 car 參數(shù)的類型應(yīng)該為 Car。

在這個(gè)例子中,編譯器必須執(zhí)行一些額外的工作來推斷類型,但它成功了。接下來,讓我們看看在提高挑戰(zhàn)難度,讓編譯器達(dá)到其能力極限時(shí),會發(fā)生什么。

推斷的局限性

首先,我們在前一個(gè) comparing 調(diào)用后面添加了一個(gè)新調(diào)用。在本例中,我們還為 lambda 表達(dá)式的參數(shù)重新引入顯式類型:public?static?Comparator?createComparator()?{

return?comparing((Car?car)?->?car.getRegistration()).reversed();}

借助顯式類型,此代碼沒有編譯問題,但現(xiàn)在讓我們丟棄類型信息,看看會發(fā)生什么:public?static?Comparator?createComparator()?{

return?comparing(car?->?car.getRegistration()).reversed();}

如您下面所見,進(jìn)展并不順利。Java 編譯器拋出了錯(cuò)誤:Sample.java:21:?error:?cannot?find?symbol

return?comparing(car?->?car.getRegistration()).reversed();

^

symbol:???method?getRegistration()

location:?variable?car?of?type?ObjectSample.java:21:?error:?incompatible?types:?Comparator?cannot?be?converted?to?Comparator

return?comparing(car?->?car.getRegistration()).reversed();

^2?errors

像上一個(gè)場景一樣,在包含 .reversed() 之前,編譯器會詢問我們將如何處理調(diào)用 comparing(car -> car.getRegistration()) 的結(jié)果。在上一個(gè)示例中,我們以 Comparable 形式返回結(jié)果,所以編譯器能推斷出 T 的類型為 Car。

但在修改過后的版本中,我們將傳遞 comparable 的結(jié)果作為調(diào)用 reversed() 的目標(biāo)。comparable 返回Comparable,reversed() 沒有展示任何有關(guān) T 的可能含義的額外信息。根據(jù)此信息,編譯器推斷 T 的類型肯定是 Object。遺憾的是,此信息對于該代碼而言并不足夠,因?yàn)?Object 缺少我們在 lambda 表達(dá)式中調(diào)用的 getRegistration() 方法。

類型推斷在這一刻失敗了。在這種情況下,編譯器實(shí)際上需要一些信息。類型推斷會分析參數(shù)、返回元素或賦值元素來確定類型,但在上下文提供的細(xì)節(jié)不足時(shí),編譯器就會達(dá)到其能力極限。

能否采用方法引用作為補(bǔ)救措施?

在我們放棄這種特殊情況之前,讓我們嘗試另一種方法:不使用 lambda 表達(dá)式,而是嘗試使用方法引用:public?static?Comparator?createComparator()?{

return?comparing(Car::getRegistration).reversed();}

編譯器對此解決方案非常滿意。它在方法引用中使用 Car:: 來推斷類型。

結(jié)束語

Java 8 為 lambda 表達(dá)式的參數(shù)引入了有限的類型推斷能力,在未來的 Java 版本中,會將類型推斷擴(kuò)展到局部變量。現(xiàn)在應(yīng)該學(xué)會省略類型細(xì)節(jié)并信任編譯器,這有助于您輕松步入未來的 Java 環(huán)境。

依靠類型推斷和適當(dāng)命名的參數(shù),編寫簡明、更富于表達(dá)且更少雜質(zhì)的代碼。只要您相信編譯器能自行推斷出類型,就可以使用類型推斷。僅在您確定編譯器確實(shí)需要您的幫助的情況下提供類型細(xì)節(jié)。原作者:Venkat Subramaniam

原文鏈接:Java 8 習(xí)慣用語

原出處: IBM Developer

來源:https://www.icode9.com/content-1-863301.html

總結(jié)

以上是生活随笔為你收集整理的java中已定义类型car_Java 8 习惯用语(8):Java 知道您的类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亚洲爽片| 国产午夜福利在线播放 | 免费看黄网站在线观看 | 日韩精品视频观看 | 免费在线国产 | 偷看洗澡一二三区美女 | 国产91黄色 | 久久精品—区二区三区舞蹈 | 18男女无套免费视频 | 日本伦理在线 | 污污网站在线看 | 超碰1000| 国产成人精品一区二区色戒 | 射精一区二区 | 一级肉体全黄裸片 | 黄色喷水网站 | 亚洲不卡视频在线 | 性色av一区 | 天堂在线中文8 | 亚洲精品91 | 少妇高潮一区二区三区99小说 | 精品美女久久久久 | 国产三级av在线播放 | 国产成人宗合 | 日韩精品在线一区二区三区 | 91精品导航 | 亚洲伦理一区 | 国产福利一区二区三区 | 亚洲20p | 又黄又爽的视频 | 高h捆绑拘束调教小说 | 海角社区登录 | 国产a一区 | 国产精品成av人在线视午夜片 | www久久99 | 免费国产| 久久九色 | 日韩欧美午夜 | 综合一区二区三区 | 国产中文字幕在线免费观看 | 在线观看免费av网站 | 国产日本精品视频 | 国产无遮挡又黄又爽 | 欧美日韩一二三四 | 黄色靠逼视频 | 爽爽免费视频 | 亚洲一区在线电影 | 四色在线 | 精品国产鲁一鲁一区二区三区 | 黄色在线网站 | 91综合视频 | 欧美在线视频播放 | 亚洲热在线视频 | 午夜色福利 | www.国产一区二区三区 | 久久加久久 | 亚洲天堂2015 | 裸体男女树林做爰 | 亚洲精品无码久久久 | 九七伦理电影 | 色八戒av| 日产mv免费观看 | 亚洲男人在线 | 国产成人精品一区二区色戒 | 国产精品久久久久久久久免费相片 | 国产精品果冻传媒 | 青青草视频国产 | 日本成人黄色片 | 琪琪秋霞午夜被窝电影网 | jizz俄罗斯 | 视频在线观看视频 | 久草在在线视频 | 国产在线1 | 亚洲乱码国产乱码精品精剪 | 成人免费毛片足控 | 久久日韩精品 | 成人一区二区av | av大片在线免费观看 | 阿v免费视频 | 天堂综合 | 男女午夜影院 | 综合色天天 | 国产熟女一区二区 | 漂亮人妻被黑人久久精品 | 正在播放经典国语对白 | 爱情岛论语亚洲入口 | 国产日韩欧美综合在线 | 午夜激情成人 | 久久男人网 | 国产精品1000部啪视频 | 精品国产区一区二 | 国产小视频免费在线观看 | 国产视频福利在线观看 | 冈本视频在线观看 | 手机看片久久 | 天堂欧美城网站网址 | 未满十八岁勿进 | 日韩毛片在线视频 | 成人在线手机视频 |