我在阅读 Java 10 中发布的新功能时发现:
Java 10
var
作为保留类型名称引入以减少冗长。它可以用作变量、方法和包名称,但我们不能将其用作类或接口名称。
是否var
类似于var
JavaScript 中的关键字?var
Java和 JavaScript之间到底有什么相同点和不同点var
?
var
两种语言在概念上的用途有些相似,但存在重要差异。
JavaScript 是一种动态类型语言。变量没有类型信息。它对可以包含的内容没有限制。它只是一个值的持有者,该值可以是任何类型。
Java 是一种静态类型语言,所有这些语句都相反。程序员必须预先说明他们的变量可以保存什么类型。它们可能像(每个类都隐式Object
扩展)一样宽松,也可能像.Object
FieldTagTestsVisitorComparator
Object objectVariable = "hello";
FieldTagTestsVisitorComparator enterpriseVariable = new FieldTagTestsVisitorComparator();
在 JavaScript 中,我可以非常简洁地编写
var age = 10;
我有一个地方可以存储我以后可以读取或操作的值。
如果我稍后在我的代码中决定我想为这个变量重新分配其他东西,那么我可以这样做。
age = {years: 10, months: 4, days: 5};
您可以清楚地看到哪些声明更适合使用。人们经常抱怨 Java 的冗长。在上面的示例中,我FieldTagTestsVisitorComparator
在同一行声明了两次。这增加了什么价值?我只是重复了自己。
var
在 Java 中旨在减少重复声明的数量。就像之前的菱形运算符一样,语言设计者正在尝试改进 Java 编译器,以便它足够聪明地推断出程序员的意图。如果可以隐含,为什么还要显式?
这实际上意味着赋值左侧的变量类型是从右侧推导出来的。
如果我用 Java 编写以下内容
var foo = new StringBuilder();
那么 Java 10+ 编译器足够聪明,可以识别右侧的字符串构建器并自动为变量foo
提供适当的类型。
这与 JavaScript 根本不同,因为虽然我没有指定类型,但类型仍然存在。我不能随后将任何我喜欢的东西分配给它:
foo = 3; // fails to compile, foo is of type StringBuilder
var
纯粹在编译时使用。编译器计算出类型,替换它,字节码就像从未使用过一样。两者在功能上没有区别
var foo = new StringBuilder();
和
StringBuilder foo = new StringBuilder();
这纯粹是一种外观上的差异,使语言更具表现力。
关于var
的状态的说明
Java 语言设计者在添加新特性时总是非常小心,不会破坏向后兼容性,因此var
具有某种特殊的地位。它不是关键字,因为拥有关键字状态会过于严格。例如,关键字不能用作标识符;我不能调用一个方法,if
因为if
它是一个关键字。
var
正如您的报价所述,是“保留类型名称”。起初这听起来很复杂,但实际上它非常描述var
' 的状态。它是 Java 保留的类型的名称。您不能命名您的类型 - 类、接口、枚举 - var
,因为这会引入歧义。
您仍然可以在所有其他上下文中自由使用“var”一词 - 方法名称、变量标识符等。
通过拥有此状态,设计人员最大限度地实现了向后兼容性(根本没有添加该功能!)。除非你有一个叫做小写的类var
——首先你在做什么选择这些可怕的名字,其次你为什么不至少遵循命名约定并调用它Var
?-- 那么你就不会受到任何重大变化的影响。
这里有一个完整的问题:Java 10 中的“var”到底是什么类型的令牌?
很好的功能,对吧?绝对是,但重要的是不要仅仅因为可以就开始在任何地方使用它。JDK 开发人员之一的 Stuart Marks 有一些出色的样式指南,我建议您阅读。
我的经验法则是,如果没有在同一行指定类型(如上面的示例中所示),那么我不使用var
. 编译器足够聪明,可以从任何有效表达式的结果中推断出类型,因此以下内容是完全有效的:
var foo = bar();
但是,如果不查看方法签名,就无法立即看出将推断出变量的类型。编译器没有歧义,但对于阅读它的人来说不太清楚。在这种情况下,为了简洁,我们牺牲了可读性。
进一步阅读
var
是 C# 中已经存在的东西。基本上,它不是声明变量类型,而是根据它被设置的类型来假设它的类型。例如:
var myString = "Hello world"
因为您将其设置为引号中的值,所以它假定它是 a String
,而不必指定如下:
String myString = "Hello world"
Var
是 中引入的一个新关键字Java 10
。行为几乎与 JavaScript 相同。请参阅下文,了解我们可以使用 Java 中的 Var 关键字做什么和不能做什么。
能
不能
更新:
var
支持泛型类型以及来自 Java 11 的 Lambda 表达式。