对于编程语言迷来说,新闻几乎比这更令人兴奋!

现在有一个状态为“候选”的本地变量类型推断的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可能是对此功能的常见反应。 对于大多数人来说,不能一直输入所有类型只是为了方便。 某些人在阅读代码时可能更喜欢看到明确记录下来的类型。 特别是,当您具有复杂的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的新本地变量类型推断相关推荐

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

    根据变量推断变量类型 对于编程语言迷来说,新闻几乎比这更令人兴奋! 现在,存在状态为"候选"的JEP 286用于本地变量类型推断 . 以及Brian Goetz的反馈请求,我很想邀 ...

  2. 根据变量推断变量类型_11位专家参与其中:本地变量类型推断是Java 10中最大的新功能

    根据变量推断变量类型 " Java 10不仅是对Java 9的简单稳定性和性能修复," 尽管Java 9是六个月前才发布的( 仅! ),这意味着对Java 10的期望可能不是很高, ...

  3. JDK10的新特性:本地变量类型var

    文章目录 简介 为什么我们需要var var使用在什么地方 var不能用在什么地方 其他var的特点 总结 简介 java以面向对象的特性显著于世并得到了蓬勃的发展.在语言的发展过程中,为了让java ...

  4. Java 编程问题:四、类型推断

    原文:Java Coding Problems 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自[ApacheCN Java 译文集],自豪地采用谷歌翻译. 本章包括 21 个涉及 JEP ...

  5. 《Python 1》--python的简介、解释器、读取键盘输入函数、变量类型推断、5个标准数据类型、字符串的内置函数、for循环、list列表、tuple元组、字典dictionary

    Python 的起源: Python 的创始人为吉多·范罗苏姆(Guido van Rossum) 1. 1989 年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的**解释程序 ...

  6. Java 10 – JEP 286:局部变量类型推断

    Java 10即将发布,RC Build可在此处获得 . 可在此处找到此发行版的目标功能. 在针对Java 10的所有JEP中,开发人员社区中最有趣且最受关注的是286:Local-Variable ...

  7. java 鲜为人知的知识点_鲜为人知的Java 8功能:广义目标类型推断

    java 鲜为人知的知识点 遍历Java 8的功能列表 , 广义目标类型推断使我震惊,因为它是一个特别有趣,鲜为人知的瑰宝. 看起来Java语言设计人员将减轻过去使用泛型(Java 5-7)时遇到的某 ...

  8. 鲜为人知的Java 8功能:广义目标类型推断

    遍历Java 8功能列表 , 广义目标类型推断使我震惊,因为它是一个特别有趣,鲜为人知的瑰宝. 看起来Java语言设计人员将减轻过去使用泛型(Java 5-7)时遇到的某些痛苦. 让我们看看他们的例子 ...

  9. java学习(二)--- 变量类型

    变量声明 type identifier [ = value][, identifier [= value] ...] ; 局部变量: 1.局部变量声明在方法.构造方法.语句块中 2.局部变量在方法. ...

最新文章

  1. win使用linux共享打印机,Ubuntu 12.04以及 Window 下使用共享打印机
  2. nginx css 304 导致图片丢失_Nginx 从入门到实战
  3. 【数据结构】单调栈和单调队列 详解+例题剖析
  4. C语言水洼数算法,C++ 数据结构之水洼的数量算法
  5. 面试官:线程顺序执行,这么多答案你都答不上来?
  6. mysql配置读写分离无效_MySQL数据库的同步配置+MySql 读写分离
  7. 三十七、细说Scrapy中的settings设置
  8. “毕设导师互选系统”项目产品宣传推广方案
  9. javascript 布尔_JavaScript布尔说明-如何在JavaScript中使用布尔
  10. python运行命令_Python中执行外部命令
  11. java的 import注解_[java]一分钟学会spring注解之@Import注解
  12. datetimepicker中文不生效_Python reStructuredText 帮助文件中文乱码
  13. 基于MATLAB的说话人语音识别声纹识别系统
  14. java 中的radix_Java Scanner radix()方法与示例
  15. Elasticsearch许可证过期导致ES用不了的问题
  16. 使用lap.lapjv实现线性分配(我主要用来作为匈牙利算法的实现)
  17. 【ICLR 2023】RankCSE:基于排序学习的无监督句子表示学习
  18. C专家编程 --- 书中案例汇编与分析(持续更新中)
  19. 懊悔!早一点遇到这份1399页Nginx笔记,我绝不会错过阿里offer!
  20. 二分查找,返回第一次出现的位置

热门文章

  1. 小白学数据:教你用Python实现简单监督学习算法
  2. 在Linux系统上部署java web项目
  3. java中实现客户姓名添加和显示
  4. jquery选择器案例分享
  5. 如何给视频中插入视频,字幕,以及去掉前后广告
  6. java实现打印直角三角形
  7. numpy 数组抽取_清晰易懂的Numpy入门教程
  8. delphi dll是否可用var参数_时间序列之向量自回归(VAR)学习重点
  9. python股票自动买卖视频教程_十分钟学会用Python交易股票
  10. adf.test_在ADF 12.2.1.3中使用基于JSON的REST Web服务