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

歡迎訪問 生活随笔!

生活随笔

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

java

Java A的新本地变量类型推断

發(fā)布時間:2023/12/3 java 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java A的新本地变量类型推断 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

對于編程語言迷來說,新聞幾乎比這更令人興奮!

現(xiàn)在有一個狀態(tài)為“候選”的本地變量類型推斷的JEP 286 。 以及Brian Goetz的反饋請求,我很想邀請您參加: http : //mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html

請這樣做,調(diào)查僅在3月9日至3月16日開放!

這不是將要實現(xiàn)的功能。 這可能實現(xiàn)。 因此,尚無特定的Java版本,這就是為什么我將Java版本命名為“ A”(對于Awesome)。

什么是局部變量類型推斷,為什么好呢?

讓我們看一下其他各種語言已經(jīng)存在了一段時間的功能。 在此博客文章中,我想討論總體思想,而不是討論可能針對Java計劃的特定實現(xiàn),因為這還為時過早,而且我當然不了解如何將其適合Java。 。

在Java和其他某些語言中,類型總是明確和冗長地聲明。 例如,您編寫如下內(nèi)容:

// Java 5 and 6 List<String> list = new ArrayList<String>();// Java 7 List<String> list = new ArrayList<>();

請注意,在Java 7中,如何通過有用的菱形運算符<>添加了一些語法糖。 它有助于以Java方式消除不必要的冗余,即通過應(yīng)用“目標類型”,這意味著類型是由“目標”定義的。 可能的目標是:

  • 局部變量聲明
  • 方法參數(shù)(從方法的外部和內(nèi)部)
  • 班級成員

由于在許多情況下, 必須明確聲明目標類型(方法參數(shù),類成員),因此Java的方法很有意義。 但是,對于局部變量,實際上不需要聲明目標類型。 由于類型定義綁定在一個非常局部的范圍內(nèi),因此無法逃脫,因此編譯器很可能會在沒有源代碼明確的情況下從“源類型”推斷出它。 這意味著,我們將能夠執(zhí)行以下操作:

// Java A as suggested in the JEP// infers ArrayList<String> var list = new ArrayList<String>();// infers Stream<String> val stream = list.stream();

在上面的示例中, var表示可變(非最終)局部變量,而val表示不可變(最終)局部變量。 請注意,從來沒有真正需要過列表類型,就像我們編寫以下內(nèi)容一樣,今天已經(jīng)推斷出了類型:

stream = new ArrayList<String>().stream();

這與lambda表達式?jīng)]有什么不同,在Java 8中我們已經(jīng)有了這種類型推斷:

List<String> list = new ArrayList<>();// infers String list.forEach(s -> {System.out.println(s); };

將lambda參數(shù)視為局部變量。 這種lambda表達式的另一種語法可能是:

List<String> list = new ArrayList<>();// infers String list.forEach((val s) -> {System.out.println(s); };

其他語言都有這個,但是好嗎?

這些其他語言包括:C#,Scala和JavaScript(如果需要的話)。 YAGNI可能是對此功能的常見反應(yīng)。 對于大多數(shù)人來說,不能一直輸入所有類型只是為了方便。 某些人在閱讀代碼時可能更喜歡看到明確記錄下來的類型。 特別是,當您具有復(fù)雜的Java 8 Stream處理管道時,很難跟蹤沿途推斷的所有類型。 在我們有關(guān)jOOλ的窗口函數(shù)支持的文章中可以看到一個示例:

BigDecimal currentBalance = new BigDecimal("19985.81");Seq.of(tuple(9997, "2014-03-18", new BigDecimal("99.17")),tuple(9981, "2014-03-16", new BigDecimal("71.44")),tuple(9979, "2014-03-16", new BigDecimal("-94.60")),tuple(9977, "2014-03-16", new BigDecimal("-6.96")),tuple(9971, "2014-03-15", new BigDecimal("-65.95"))) .window(Comparator.comparing((Tuple3<Integer, String, BigDecimal> t) -> t.v1, reverseOrder()).thenComparing(t -> t.v2), Long.MIN_VALUE, -1) .map(w -> w.value().concat(currentBalance.subtract(w.sum(t -> t.v3).orElse(BigDecimal.ZERO)) ));

上面實現(xiàn)了運行總計計算,得出:

+------+------------+--------+----------+ | v0 | v1 | v2 | v3 | +------+------------+--------+----------+ | 9997 | 2014-03-18 | 99.17 | 19985.81 | | 9981 | 2014-03-16 | 71.44 | 19886.64 | | 9979 | 2014-03-16 | -94.60 | 19815.20 | | 9977 | 2014-03-16 | -6.96 | 19909.80 | | 9971 | 2014-03-15 | -65.95 | 19916.76 | +------+------------+--------+----------+

盡管由于現(xiàn)有Java 8的有限類型推斷功能而需要聲明Tuple3類型( 另請參見有關(guān)廣義目標類型推斷的本文 ),但是您是否可以跟蹤所有其他類型? 您可以輕松預(yù)測結(jié)果嗎? 有些人喜歡短款,有些則聲稱:

@lukaseder我總是在Scala中聲明我的類型。 我真的認為除了語法糖之外,這沒有給Java的游戲增加任何東西。

— Steve Chaloner(@steve_objectify) 2016年3月10日

另一方面,您是否想手動寫下類似Tuple3<Integer, String, BigDecimal> ? 或者,在使用jOOQ時 ,您更喜歡以下哪個版本的相同代碼?

// Explicit typing // ---------------------------------------- for (Record3<String, Integer, Date> record : ctx.select(BOOK.TITLE, BOOK.ID, BOOK.MODIFIED_AT).from(BOOK).where(TITLE.like("A%")) ) {// Do things with recordString title = record.value1(); }// "Don't care" typing // ---------------------------------------- for (Record record : ctx.select(BOOK.TITLE, BOOK.ID, BOOK.MODIFIED_AT).from(BOOK).where(TITLE.like("A%")) ) {// Do things with recordString title = record.getValue(0, String.class); }// Implicit typing // ---------------------------------------- for (val record : ctx.select(BOOK.TITLE, BOOK.ID, BOOK.MODIFIED_AT).from(BOOK).where(TITLE.like("A%")) ) {// Do things with recordString title = record.value1(); }

我敢肯定,很少有人真的愿意顯式地寫下整個泛型類型,但是如果您的編譯器仍然可以記住這一點,那真是太棒了,不是嗎? 這是一個可選功能。 您始終可以恢復(fù)為顯式類型聲明。

使用地點差異的邊緣案例

沒有這種類型推斷,有些事情是不可能的,它們與使用站點的差異以及Java中實現(xiàn)的泛型的細節(jié)有關(guān)。 使用使用場所差異和通配符,可以構(gòu)造無法分配給任何東西的“危險”類型,因為它們是不確定的。 有關(guān)詳細信息,請閱讀Ross Tate關(guān)于在Java的Type System中馴服通配符的論文 。

當從方法返回類型暴露時,使用站點差異也是一個痛苦,如在某些庫中可以看到的:

  • 不在乎他們給用戶帶來的痛苦
  • 沒有找到更好的解決方案,因為Java沒有聲明站點差異
  • 忽略了這個問題

一個例子:

interface Node {void add(List<? extends Node> children);List<? extends Node> children(); }

想象一下一個樹數(shù)據(jù)結(jié)構(gòu)庫,其中樹節(jié)點返回其子級列表。 從技術(shù)上講正確的子類型為List<? extends Node> List<? extends Node>因為子級是Node子類型,并且使用Node子類型列表是完全可以的。

從API設(shè)計的角度來看,在add()方法中接受此類型非常有用。 例如,它允許人們添加List<LeafNode> 。 但是,從children()返回它是可怕的,因為現(xiàn)在唯一的選擇是:

// Raw type. meh List children = parent.children();// Wild card. meh List<?> children = parent.children();// Full type declaration. Yuk List<? extends Node> children = parent.children();

使用JEP 286,我們也許可以解決所有這些問題,并擁有第四個不錯的選擇:

// Awesome. The compiler knows it's // List<? extends Node> val children = parent.children();

結(jié)論

局部變量類型推斷是一個熱門話題。 它是完全可選的,我們不需要它。 但這使很多事情變得容易得多,尤其是在使用大量仿制藥時。 我們已經(jīng)看到,在使用lambda表達式和復(fù)雜的Java 8 Stream轉(zhuǎn)換時,類型推斷是一項致命功能。 當然,要在一條較長的語句中跟蹤所有類型會比較困難,但是同時,如果拼出了這些類型,則會使該語句非常難以閱讀(并且通常也很難編寫)。

類型推斷有助于使開發(fā)人員提高工作效率,而又不放棄類型安全性。 實際上,這鼓勵了類型安全,因為API設(shè)計人員現(xiàn)在不那么愿意向用戶公開復(fù)雜的泛型類型,因為用戶可以更輕松地使用這些類型( 請參見jOOQ示例 )。

實際上,此功能已經(jīng)在各種情況下在Java中提供,只是在為局部變量賦值并為其命名時不存在。

無論您的意見是什么:請確保將其分享給社區(qū)并回答此調(diào)查: http : //mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html

期待Java A,A代表Awesome。

翻譯自: https://www.javacodegeeks.com/2016/03/java-new-local-variable-type-inference.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Java A的新本地变量类型推断的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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