4

我在阅读 Java 10 中发布的新功能时发现:

Java 10var作为保留类型名称引入以减少冗长。它可以用作变量、方法和包名称,但我们不能将其用作类或接口名称。

是否var类似于varJavaScript 中的关键字?varJava和 JavaScript之间到底有什么相同点和不同点var

4

3 回答 3

17

var两种语言在概念上的用途有些相似,但存在重要差异。

JavaScript 是一种动态类型语言。变量没有类型信息。它对可以包含的内容没有限制。它只是一个值的持有者,该值可以是任何类型。

Java 是一种静态类型语言,所有这些语句都相反。程序员必须预先说明他们的变量可以保存什么类型。它们可能像(每个类都隐式Object扩展)一样宽松,也可能像.ObjectFieldTagTestsVisitorComparator

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();

但是,如果不查看方法签名,就无法立即看出将推断出变量的类型。编译器没有歧义,但对于阅读它的人来说不太清楚。在这种情况下,为了简洁,我们牺牲了可读性。


进一步阅读

于 2019-10-02T18:51:30.467 回答
3

var是 C# 中已经存在的东西。基本上,它不是声明变量类型,而是根据它被设置的类型来假设它的类型。例如:

var myString = "Hello world"

因为您将其设置为引号中的值,所以它假定它是 a String,而不必指定如下:

String myString = "Hello world"
于 2018-04-03T18:38:45.950 回答
-1

Var是 中引入的一个新关键字Java 10。行为几乎与 JavaScript 相同。请参阅下文,了解我们可以使用 Java 中的 Var 关键字做什么和不能做什么。

  • 使用 var 关键字声明任何数据类型
  • 用于局部变量声明

不能

  • 用于实例和全局变量声明
  • 用作通用类型
  • 与泛型类型一起使用
  • 无需显式初始化即可使用
  • 与 Lambda 表达式一起使用
  • 用于方法参数和返回类型

更新: var支持泛型类型以及来自 Java 11 的 Lambda 表达式。

于 2021-11-29T13:29:00.470 回答