转载

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

介绍 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          ()    

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

也有人提出问题,是否其他类关键字结构也可能是有用的,例如为只读变量提供不同的结构。虽然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读者交流群 JEP 286 提议在Java局部变量中引入类型推断 (已满),InfoQ读者交流群(#2) JEP 286 提议在Java局部变量中引入类型推断 )。

原文  http://www.infoq.com/cn/news/2016/03/java-inference
正文到此结束
Loading...