写点什么

JEP 286 提议在 Java 局部变量中引入类型推断

  • 2016-03-16
  • 本文字数:1864 字

    阅读完需:约 6 分钟

介绍 JEP 286 的提议已经发送到 JEP 讨论平台(platform-jep-discuss)邮件列表中,如果能够实现,将在 Java 局部变量中引入类型推断。由于这只是一个初期阶段的提议,因此并没有计划在 Java 哪个版本中实现,甚至可能不会实现。

类型推断是指声明一个变量但无需指定其相关联的类型。类型推断在 Java 中已经存在一段时间;Java 5 中引入泛型时,便是利用类型推断处理泛型方法。Java 7 中增加了钻石(diamond)运算符 <>(Coin 项目中的一部分)允许 List 类型的变量被初始化而不需要 ArrayList<> 类型的约束。最近,Java 8 中增加了 lambdas 和 streams 功能,可以在方法链中推断类型以及 lambda 参数的形参类型。通常可以从上下文或初始化程序的表达式中推断出类型的信息。类似地如果表达式是无类型的 (如 0 或 null) 则不一定会得到正确的类型推断。类型推断相关内容甚至占据了 Java 语言规范整个第18 章

因为类型推断早已经被支持,并且可以有效地推断final 局部变量,设想它被用于Java 局部变量并不是一个大难题。它仅用于局部变量(这些变量通过方法或lambda 函数体定义)而不是方法签名或字段签名。

提议中对于声明推断类型的变量提供了一个类关键字var。在支持类型推断的语言中,通常把类型放在变量名的后面,这样一个变量或参数可以定义为aNumber:Int 或者aNumber,有效地将类型的定义(:Int)作为可选的后缀。但是,Java 是基于C 语言,把类型放在第一位,而且这几乎是不可改变的。这样类关键字var 被用来当作占位符代表“任何类型”,类似于其他语言中变量的定义方式。因此,它有可能写出这样的语句:

var proposal = "JEP-286";这种情况下,变量的类型将被推断为字符串,表达式的实际类型在另一边。这也将简化泛型数据结构,例如:

var phonebook = new HashMap<string>()</string>值得注意的是,这种类型会被推断为实际的类型;这种情况下,应该优先使用接口来代替。然而在大多数情况下鉴于它仅适用于局部变量,这种差别并不是特别有意义的。

也有人提出问题,是否其他类关键字结构也可能是有用的,例如为只读变量提供不同的结构。虽然 final var 可以拿来使用(对于 final 的有效推断已经比较成熟,也许没有必要使用其他类关键字结构),但是是否还有其他的可能性,这个灵感来自其他语言,如 const,val 或 let。对于变量的声明也会有其他的可能,例如 auto。JEP 提议者请求大家给予反馈。有一项调查来征求大家的意见,这样是很有用的。

建议方案的实施不是使 var(或 auto/let/def/val …)成为一个新的关键字,这将会导致已经使用它们作为标识符的 Java 程序作废。相反,他们会保留这些类型名称,像 Object 或 String 一样有效。用 var 作为现有类型(class 或 interface)的应用程序将被中断,但这将打破现有的 java 命名规则。

通过原型实现和扫描现有 JDK 源代码,结果显示大多数情况下,局部变量切换为使用 var 是没有问题的。少数情况下不能成功地推断出结果,或者是因为没有初始化值,初始化为 null(当然可以是任何类型) 或者是因为推断出了比指定类型更严格的类型 (例如指定类型为 List,推断结果却是 ArrayList)。这确实表明,这个想法在实践中是可行的,在大多数情况下是有用的。

在 JDK 源代码下运行原型,结果如下:

  • 83.5% 推断出在源代码中存在的准确类型
  • 4% 推断出另一个可表示的类型(通常是更精准的类型)
  • 0% 由于推断的类型不可表示被拒绝
  • 8.5% 由于没有初始化被拒绝
  • 3% 由于初始化值为 null 被拒绝
  • 0.5% 由于需要一个目标类型被拒绝

如果我们排除由于没有初始化或初始化结果为 null 而被拒绝的案例,我们可以发现超过 99% 的局部变量可以被推断,95% 可以推断出正确的结果。

有效的 final 局部变量 (所有局部变量的 77%):

  • 86% 推断出在源代码中存在的准确类型
  • 4% 推断出另一个可表示的类型式(通常是更精准的类型)
  • 0% 由于推断的类型不可表示被拒绝
  • 8% 由于没有初始化被拒绝
  • 0.5% 由于初始化值为 null 被拒绝
  • 0.5% 由于需要一个目标类型被拒绝

提议中把这部分内容加入 Java 语言未来版本中,将会在 JEP 286 旗帜下进行讨论;如果有任何意见,请与 2016 年 3 月 16 日调查问卷关闭之前填写问卷信息反馈给Java 团队。

查看英文原文: JEP 286 Proposes Extending Type Inference to Local Variables in Java


感谢张龙对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群InfoQ 好读者(已满),InfoQ 读者交流群(#2)InfoQ 好读者)。

2016-03-16 19:001766
用户头像

发布了 31 篇内容, 共 10.0 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

双帆与雾洋:腾讯TAD Sim 2.0的仿真大航海

脑极体

架构师训练营第三周作业

Geek_2dfa9a

了解概率知识,概率作为机器学习的底层逻辑

古月木易

概率

奈学教育:“混沌工程”的基本理念和使用原则

奈学教育

混沌工程

组合模式例子

GalaxyCreater

设计模式

第三周作业

冯凯

奈学教育:“混沌工程”的基本理念和使用原则

古月木易

混沌工程

架构师训练营第三周作业

Geek_2dfa9a

设计模式

eazonshaw

极客大学架构师训练营

架构师训练营」第 3 周作业

edd

极客大学架构师训练营

使用了 iOS 14 发布的翻译工具,觉得还差点儿意思

神经星星

apple 机器翻译 翻译软件 WWDC2020 语音识别

架构师训练营第三周总结

Geek_2dfa9a

第三周学习总结

第三周作业一

飞翔的风

第三周设计模式命题作业

石刻掌纹

第三周·作业一·命题作业

刘璐

第三周作业2

飞翔的风

架构师训练营 第三周作业

孙有能希

极客大学架构师训练营 组合模式

第三周学习总结

冯凯

手写单例模式

GalaxyCreater

设计模式

架构师 0 期 | 面向对象的设计模式

刁架构

极客大学架构师训练营

【总结】架构师的基本能力之-代码重构

魔曦

架构师 极客大学架构师训练营 代码重构

了解概率知识,概率作为机器学习的底层逻辑

奈学教育

概率

总结03-代码重构

梦子说

极客大学架构师训练营 课程总结

架构师训练营第三章作业

饶军

week3作业一

任鑫

架构

架构师训练营--第三周作业

_MISSYOURLOVE

极客大学架构师训练营 第三周

Lesson 3 设计模式 心得笔记

edd

区块链+医疗,能否有效避免问题疫苗?

CECBC

区块链技术 溯源 疫苗

昆明全国领先打响“公共资源交易+区块链”新生态

CECBC

区块链技术 存证 昆易链

单例模式的九种实现 & 组合模式练习

Geek_2dfa9a

JEP 286 提议在Java局部变量中引入类型推断_Java_Alex Blewitt_InfoQ精选文章