Java10中的var是什么,相当于JavaScript?
What is var in Java 10, and is comparable to JavaScript?
我在阅读 Java 10 中发布的新功能时发现:
Java 10 introduced var
as a reserve type name to reduce verbosity.
It can be used as a variable, method, and package name, but we cannot
use it as a class or interface name.
var
是否与Java脚本中的var
关键字相似? Java 的 var
和 JavaScript 的 var
到底有什么相同点和不同点?
var
已经在 C# 中了。基本上,它不是声明一个变量类型,而是根据它被设置的类型来假定它的类型。例如:
var myString = "Hello world"
因为您将其设置为引号中的值,所以它假定它是 String
,而不必像这样指定:
String myString = "Hello world"
var
在这两种语言中的用途在概念上有些相似,但存在重要差异。
Java脚本是dynamically typed language。变量没有类型信息。它对它可以包含的内容没有限制。它只是一个值的持有者,值可以是任何类型。
Java 是一种静态类型语言,所有这些语句的情况正好相反。程序员必须预先说明他们的变量可以容纳什么类型。它们可能像 Object
一样宽松(每个 class 隐含地扩展 Object
)或像 FieldTagTestsVisitorComparator
.
一样具体
Object objectVariable = "hello";
FieldTagTestsVisitorComparator enterpriseVariable = new FieldTagTestsVisitorComparator();
在Java脚本中,我可以写得很简洁
var age = 10;
我有一个地方可以存储一个值,以后我可以读取或操作它。
如果我稍后在代码中决定要为该变量重新分配其他内容,那么我可以这样做。
age = {years: 10, months: 4, days: 5};
您可以清楚地看到哪些声明更好用。人们经常抱怨 Java 冗长。在我上面的例子中,我在同一行上声明了两次 FieldTagTestsVisitorComparator
。这增加了什么价值?我刚刚重复了一遍。
var
in Java 寻求在 reduce the amount of repeated declarations. Like the diamond operator 之前,语言设计者正在努力改进 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();
纯粹是cosmetic difference让语言更富表现力
关于var
状态的说明
Java 语言设计者在添加新功能时总是非常小心,以免破坏向后兼容性,因此 var
具有特殊的地位。它不是关键字,因为具有关键字状态会过度限制。例如,关键字不能用作标识符;我不能有一个名为 if
的方法,因为 if
是一个关键字。
var
正如您的引文所述,是 "reserved type name"。乍一看这听起来很复杂,但实际上它非常描述了 var
的状态。它是 Java 保留的类型的名称。您不能命名您的类型 - classes、接口、枚举 - var
,因为那样会引起歧义。
您仍然可以在所有其他上下文中自由使用 "var" 一词 - 方法名称、变量标识符等。
通过拥有这种状态,设计者已经最大限度地向后兼容(除了根本不添加该功能!)。除非你有一个叫做小写 var
的 class——首先你选择这些糟糕的名字是为了什么,其次你为什么不至少遵循命名约定并将它命名为 Var
? -- 这样您就不会受到任何重大更改的影响。
这里有一个完整的问题:
很好的功能,对吧?这绝对是,但重要的是不要仅仅因为可以就开始在任何地方使用它。 JDK 开发人员之一斯图尔特·马克斯 (Stuart Marks) 有一些优秀的 style guidelines,我建议您阅读。
我的经验是,如果类型没有在同一行指定(如上面的例子),那么我不使用 var
。编译器足够聪明,可以从任何有效表达式的结果中推断出类型,因此以下内容完全有效:
var foo = bar();
但是,如果不查看方法签名,将无法立即推断出变量的类型。编译器没有歧义,但阅读它的人就不太清楚了。在这种情况下,我们为了简洁而牺牲了可读性。
进一步阅读
Var
是 Java 10
中引入的新关键字。行为与 JavaScript 几乎相同。请参阅下文,了解我们可以使用 Java.
中的 Var 关键字做什么和不能做什么。
可以
- 使用 var 关键字声明任何数据类型
- 在局部变量声明中使用
不能
- 用于实例和全局变量声明
- 用作通用类型
- 与泛型一起使用
- 无需显式初始化即可使用
- 与 Lambda 表达式一起使用
- 用于方法参数和return类型
更新:
var
支持泛型类型以及来自 Java 11.
的 Lambda 表达式
我在阅读 Java 10 中发布的新功能时发现:
Java 10 introduced
var
as a reserve type name to reduce verbosity. It can be used as a variable, method, and package name, but we cannot use it as a class or interface name.
var
是否与Java脚本中的var
关键字相似? Java 的 var
和 JavaScript 的 var
到底有什么相同点和不同点?
var
已经在 C# 中了。基本上,它不是声明一个变量类型,而是根据它被设置的类型来假定它的类型。例如:
var myString = "Hello world"
因为您将其设置为引号中的值,所以它假定它是 String
,而不必像这样指定:
String myString = "Hello world"
var
在这两种语言中的用途在概念上有些相似,但存在重要差异。
Java脚本是dynamically typed language。变量没有类型信息。它对它可以包含的内容没有限制。它只是一个值的持有者,值可以是任何类型。
Java 是一种静态类型语言,所有这些语句的情况正好相反。程序员必须预先说明他们的变量可以容纳什么类型。它们可能像 Object
一样宽松(每个 class 隐含地扩展 Object
)或像 FieldTagTestsVisitorComparator
.
Object objectVariable = "hello";
FieldTagTestsVisitorComparator enterpriseVariable = new FieldTagTestsVisitorComparator();
在Java脚本中,我可以写得很简洁
var age = 10;
我有一个地方可以存储一个值,以后我可以读取或操作它。
如果我稍后在代码中决定要为该变量重新分配其他内容,那么我可以这样做。
age = {years: 10, months: 4, days: 5};
您可以清楚地看到哪些声明更好用。人们经常抱怨 Java 冗长。在我上面的例子中,我在同一行上声明了两次 FieldTagTestsVisitorComparator
。这增加了什么价值?我刚刚重复了一遍。
var
in Java 寻求在 reduce the amount of repeated declarations. Like the diamond operator 之前,语言设计者正在努力改进 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();
纯粹是cosmetic difference让语言更富表现力
关于var
状态的说明
Java 语言设计者在添加新功能时总是非常小心,以免破坏向后兼容性,因此 var
具有特殊的地位。它不是关键字,因为具有关键字状态会过度限制。例如,关键字不能用作标识符;我不能有一个名为 if
的方法,因为 if
是一个关键字。
var
正如您的引文所述,是 "reserved type name"。乍一看这听起来很复杂,但实际上它非常描述了 var
的状态。它是 Java 保留的类型的名称。您不能命名您的类型 - classes、接口、枚举 - var
,因为那样会引起歧义。
您仍然可以在所有其他上下文中自由使用 "var" 一词 - 方法名称、变量标识符等。
通过拥有这种状态,设计者已经最大限度地向后兼容(除了根本不添加该功能!)。除非你有一个叫做小写 var
的 class——首先你选择这些糟糕的名字是为了什么,其次你为什么不至少遵循命名约定并将它命名为 Var
? -- 这样您就不会受到任何重大更改的影响。
这里有一个完整的问题:
很好的功能,对吧?这绝对是,但重要的是不要仅仅因为可以就开始在任何地方使用它。 JDK 开发人员之一斯图尔特·马克斯 (Stuart Marks) 有一些优秀的 style guidelines,我建议您阅读。
我的经验是,如果类型没有在同一行指定(如上面的例子),那么我不使用 var
。编译器足够聪明,可以从任何有效表达式的结果中推断出类型,因此以下内容完全有效:
var foo = bar();
但是,如果不查看方法签名,将无法立即推断出变量的类型。编译器没有歧义,但阅读它的人就不太清楚了。在这种情况下,我们为了简洁而牺牲了可读性。
进一步阅读
Var
是 Java 10
中引入的新关键字。行为与 JavaScript 几乎相同。请参阅下文,了解我们可以使用 Java.
可以
- 使用 var 关键字声明任何数据类型
- 在局部变量声明中使用
不能
- 用于实例和全局变量声明
- 用作通用类型
- 与泛型一起使用
- 无需显式初始化即可使用
- 与 Lambda 表达式一起使用
- 用于方法参数和return类型
更新:
var
支持泛型类型以及来自 Java 11.