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

歡迎訪問 生活随笔!

生活随笔

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

java

根据变量推断变量类型_Java A的新本地变量类型推断

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

根據變量推斷變量類型

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

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

請這樣做,調查僅在3月9日至3月16日開放!

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

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

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

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

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

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

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

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

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

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

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

這與lambda表達式沒有什么不同,在Java 8中我們已經有了這種類型推斷:

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

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

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

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

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

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)) ));

上面實現了一個運行總計計算,得出:

+------+------------+--------+----------+ | 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 | +------+------------+--------+----------+

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

@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(); }

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

使用地點差異的邊緣案例

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

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

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

一個例子:

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

想象一下一個樹數據結構庫,其中樹節點返回其子級列表。 在技??術上正確的子類型為List<? extends Node> List<? extends Node>因為子級是Node子類型,并且使用Node子類型列表是完全可以的。

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

// 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();

結論

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

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

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

無論您的意見是什么:請確保將其分享給社區并回答此調查: 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

根據變量推斷變量類型

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。