var 关键字也能让我们更有效地使用匿名类,它可以引用那些不可描述的类型。一般来说是可以在匿名类中添加字段的,但是你不能在别的地方引用这些字段,因为它需要变量在赋值时指定类型的名称。比如下面这段代码就不能通过编译,因为 productInfo 的类型是 Object,你不能通过 Object 类型来访问 name 和 total 字段。
使用 var 可以打破这个限制。把一个匿名类对象赋值给以 var 声明的局部变量时,它会推断出匿名类的类型,而不是把它当作其父类类型。因此,匿名类上声明的字段就可以引用到。
既然要同时考虑到可读性和 var ,那么如何折衷就成了一个新问题,一个建议是:关注变量名,这很重要!因为 var 失去代码的易读性,看到这样的代码你根本不知道代码的意图是什么,这就使得起好一个变量名更加重要。理论上这是JAVA程序员应努力的方面之一,实际上许多 Java 代码可读性的问题根本不在语言的特性本身,而存在于一些变量的命名不太恰当上。
IDE 中的类型推断
许多 IDE 都有提取局部变量的功能,它们可以正确地推断出变量的类型,并为你写出来。这一特性与 Java 10 的 var 有一些重复。IDE 的这个特性和 var 一样都可以消除显式书写类型的必要性,但是它们在其它方面有一些不同。
局部提取功能会在代码中生成完整的、类型明确的局部变量。而 var 则是消除了在代码写显式书写类型的必要。所以虽然他们在简化书写代码方面有着类似的作用,但 var 对代码可读性的影响是局部提取功能所不具备的。就像我们前面提到,它多数时候会提高可读性,但有时候会可能会降低可读性。
与其它编程语言比较
Java 并不是首先实现变量类型推断的语言。类型推断在近几十年来被广泛应用于其它语言中。实际上,Java 10 中通过 var 带来的类型推断非常有限,形式上也相对拘束。这是一种简单的实现,可以将与 var 声明相关的编译错误限制在一条语句当中,因为 var 推断算法只需要计算赋值给变量的表达式的类型。此外,用在大多数语言中的 Hindley-Milner 类型推断算法在最坏的情况下会花费指数级时间,这会降低 javac 的速度。
总结
var 对于 Java 语言的生产力和可读性来说是一项很不错的新特性,但不应该止步于此。将来版本的 Java 将会继续保持语言的革新和现代性。举例来说,在 Java 10 发布仅仅 6 个月之后,就将发布并长期支持的 Java 11,其 var 关键字将可以在 lambda 表达式的参数中使用。这能让你拥有正式的参数类型推断能力,这很有用,不过,你还是需要加上 Java 注解,下面是例子: