写点什么

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:001771
用户头像

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

关注

评论

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

手把手带你漫游语音识别世界|入门到实战

攻城先森

音视频 语音识别 内容合集 签约计划第二季

Apache APISIX 助力便利充电创领者小电,实现云原生方案

API7.ai 技术团队

运维 云原生 物联网 网关 Apache APISIX

Structuring: 魔法诞生之法

mtfelix

28天写作

【docker 总结】第二篇 - Image 镜像

Brave

Docker 12月日更

初学者也能看懂的 Vue3 源码中那些实用的基础工具函数

若川

JavaScript vue.js 签约计划第二季

尤雨溪推荐神器 ni ,能替代 npm/yarn/pnpm ?简单好用!源码揭秘!

若川

JavaScript vue.js 前端 签约计划第二季

[Pulsar] DLQ原理

Zike Yang

Apache Pulsar 12月日更

前端开发:正确安装nvm的方法(非常详细)

三掌柜

28天写作 28 12月日更 12月

大学生要远离宿舍

Tiger

28天写作

go语言技术探究--合集

en

内容合集 签约计划第二季

效能研发:做一款GraphQL代码生成器

梁龙先森

签约计划第二季

语音识别之降噪技术

攻城先森

音视频 语音识别 智能降噪 签约计划第二季

手把手教你提交Jar包到Maven公共仓库 | 萌新写开源02

Zhendong

Java maven

阿里Java编码手册实战详解-命名规范篇

JavaEdge

12月日更

尤雨溪几年前开发的“玩具 vite”,才100多行代码,却十分有助于理解 vite 原理

若川

JavaScript vue.js 前端 签约计划第二季

让容器跑得更快:CPU Burst 技术实践

阿里巴巴云原生

阿里云 容器 云原生 cpu CPU调度

我们的护城河在哪

hackstoic

商业模式

分布式系统的架构演进过程(二)

卢卡多多

28天写作 12月日更

Vue 3.2 发布了,那尤雨溪是怎么发布 Vue.js 的?

若川

JavaScript vue.js 前端 签约计划第二季

简历应该这样写

xcbeyond

面试技巧 28天写作 12月日更

何为异步流

喵叔

28天写作 12月日更

信息

Nydia

前端工程建设那些事

梁龙先森

内容合集 签约计划第二季

Go+ JSON 编码和解码处理教程(5.4)

liuzhen007

28天写作 12月日更

浅谈数据资产

圣迪

数据 数据资产

Kafka 在消息队列领域为何如此流行?

老周聊架构

kafka 内容合集 签约计划第二季

Prometheus Exporter (二十六)Statsd Exporter

耳东@Erdong

Prometheus 28天写作 exporter 12月日更 StatsD

日常的情绪控制

搬砖的周狮傅

情绪控制

Game On Serverless:SAE 助力广州小迈提升微服务研发效能

阿里巴巴云原生

阿里云 Serverless 云原生 SAE 合作

javascript中获取 DOM 元素的几种方式

你好bk

JavaScript 前端 大前端 DOM BOM

Vue 团队公开快如闪电的全新脚手架工具 create-vue,未来将替代 Vue-CLI,才300余行代码,学它!

若川

JavaScript vue.js 前端 签约计划第二季

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