局部变量类型推理应该被添加到Java中吗?这就是Java语言团队现在正在思考的问题。
局部变量类型推理
JEP-286建议使用一个新的伪关键词(被视为 "保留的类型名称")来增加局部变量的推理。
我们试图通过减少与编写Java代码相关的仪式来改善开发者的体验,同时保持Java对静态类型安全的承诺,允许开发者省略通常不必要的局部变量类型的清单声明。
有人提出了一些可能的关键字。
- var- 用于可变的局部变量
- val--用于最终的(不可变的)局部变量
- let- 用于最终的(不可变的)局部变量
- auto--好吧,让我们忽略它吧......
考虑到实现策略,目前的final 关键字似乎仍将被接受在所有的选项前面,因此所有这些都将是最终(不可变)变量。
- final var- 将可变的局部变量变为最终变量
- final val--多余的附加修饰符
- finallet--多余的附加修饰符
因此,选择似乎是在Java中加入这些组合之一。
- var和final var
- var和val- 但final var和final val也有效
- var和let--但final var和final let也有效。
从广义上讲,我对这个功能不感兴趣,也不相信它真的能让Java变得更好。虽然IDE可以减轻编码时类型信息的损失,但我预计一些代码审查会明显困难(因为它们是在IDE之外完成的)。还应注意的是,C#的编码标准警告不要过度使用这一特性。
当类型从赋值的右边看不出来时,不要使用var。
不要依靠变量名称来指定变量的类型。它可能不正确。
说了以上这些,我怀疑停止这个功能的可能性很小。这篇博文的其余部分主要讨论为Java选择正确的选项
Java的最佳选择
当这个功能公布后,Scala和Kotlin的爱好者自然开始争论var和val的问题。然而,虽然在其他语言中的优先权很好考察,但不一定适用,它是Java的最佳选择。
Java的最佳选择可能不同的主要原因是历史。Scala和Kotlin从一开始就有这个功能,而Java却没有。我想说明为什么我认为val或let对Java来说是错误的,因为这个历史。
考虑一下下面的代码。
public double parSpread(SwapLeg leg) {
本地变量的类型推理会很好地适用于它。但是,让我们说,有一行的类型不清楚,所以我们选择保留它以增加清晰度(根据C#的指导方针)。
public double parSpread(SwapLeg leg) {
好吧,你可能会说。但是,如果这段代码是在一个坚持把每个局部变量都标记为final的团队中写的呢。
public double parSpread(
突然间,我们有了一个混乱。代码的某些部分使用final来表示一个 "最终的"(不可变的)局部变量。而代码的其他部分则使用val。这种混合是完全错误的,而且这种混合是你在Scala或Kotlin中得不到的。
(也许你没有在每个局部变量上使用final来编码?我知道我没有。但我知道这是一个相当普遍的编码标准,旨在增加代码的安全性并减少错误)。
将上述情况与另一种情况进行对比。
public double parSpread(
这在Java内部是比较一致的。final仍然是各地用来获取final(不可变)变量的机制。如果你像我一样,不担心final关键字,它就会减少到这样。
public double parSpread(
我理解许多读者现在的反对意见--认为应该有两个新的 "关键字",一个用于可变的局部变量,一个用于不可变的局部变量,而且两者的长度/权重应该相同(或者可变的那个应该更长),以推动人们更广泛地使用不可变的形式。
但是在Java中,这真的没有那么简单。我们有最终关键字已经很多年了。忽视它的结果是令人不快的和不一致的混乱。
总结
我个人根本不喜欢局部变量类型推理。但是如果我们要拥有它,我们必须让它很好地适应现有的语言。
我认为val或let根本不适合Java,因为final已经存在,而且在那个空间里有明确的含义。虽然不是很理想,但我必须为var和final var争辩,因为这是唯一符合现有语言的关键标准的组合。