简体   繁体   English

Java 10 中的 var 是什么,可与 JavaScript 相媲美?

[英]What is var in Java 10, and is comparable to JavaScript?

I was reading about the new features released in Java 10 and I found this:我正在阅读 Java 10 中发布的新功能,我发现了这一点:

Java 10 introduced var as a reserve type name to reduce verbosity. Java 10 引入var作为保留类型名称以减少冗长。 It can be used as a variable, method, and package name, but we cannot use it as a class or interface name.它可以用作变量、方法和包名,但我们不能将其用作类或接口名。

Is var similar to the var keyword in JavaScript? var类似于 JavaScript 中的var关键字吗? What exactly are the similarities and the differences between Java's var and JavaScript's var ? Java 的var和 JavaScript 的var究竟有何异同?

var serves a somewhat conceptually similar purpose in both languages, but there are important differences. var在这两种语言中在概念上具有相似的用途,但存在重要差异。

JavaScript is a dynamically typed language . JavaScript 是一种动态类型语言 A variable does not have type information.变量没有类型信息。 It does not have restrictions on what it can contain.它对可以包含的内容没有限制。 It is just a holder for a value, and the value can be of any type.它只是一个值的持有者,该值可以是任何类型。

Java is a statically typed language and the opposite is true for all of those statements. Java 是一种静态类型语言,所有这些语句的情况恰恰相反。 A programmer has to say up-front what type their variable can hold.程序员必须预先说明他们的变量可以容纳什么类型。 They may be as lenient as Object (every class extends Object implicitly) or as specific as FieldTagTestsVisitorComparator .它们可能像Object一样宽松(每个类都隐式地扩展Object )或像FieldTagTestsVisitorComparator一样具体。

Object objectVariable = "hello";
FieldTagTestsVisitorComparator enterpriseVariable = new FieldTagTestsVisitorComparator();

In JavaScript, I can very concisely write在 JavaScript 中,我可以非常简洁地编写

var age = 10;

and I have a place in which to store a value which I can read or manipulate later.我有一个地方可以存储一个我可以稍后读取或操作的值。

If I decide later in my code that I want to re-assign something else to this variable then I can do so.如果我稍后在我的代码中决定要为这个变量重新分配其他东西,那么我可以这样做。

age = {years: 10, months: 4, days: 5};

You can see clearly see which declarations are nicer to work with.您可以清楚地看到哪些声明更适合使用。 People often complain about Java's verbosity.人们经常抱怨 Java 的冗长。 In my example above, I've declared FieldTagTestsVisitorComparator twice on the same exact line.在上面的示例中,我在同一行上两次声明了FieldTagTestsVisitorComparator What value is that adding?这增加了什么价值? I've just repeated myself.我刚刚重复了自己。

var in Java seeks to reduce the amount of repeated declarations . Java 中的var试图减少重复声明的数量 Like the diamond operator before it, the language designers are trying to improve the Java compiler so that it is clever enough to make inferences about what programmers are intending.就像之前的菱形运算符一样,语言设计者正在努力改进 Java 编译器,使其足够聪明,可以推断出程序员的意图。 Why should something be explicit if it can be implicit?如果某事可以是隐式的,为什么要显式呢?

What this means in practice is that the type of the variable on the left-hand-side of the assignment is deduced from the right-hand-side.这在实践中意味着赋值左侧的变量类型是从右侧推导出来的。

If I write the following in Java如果我用Java编写以下内容

var foo = new StringBuilder();

then the Java 10+ compilers are clever enough to recognize a string builder on the right-hand-side and to automatically give the variable foo the appropriate type.那么 Java 10+ 编译器足够聪明,可以识别右侧的字符串构建器并自动为变量foo适当的类型。

This fundamentally differs from JavaScript because although I have not specified the type, a type is still present .这与 JavaScript 有着根本的不同,因为虽然我没有指定类型,但类型仍然存在 I cannot subsequently assign anything I like to it:我不能随后为它分配任何我喜欢的东西:

foo = 3; // fails to compile, foo is of type StringBuilder

var is purely used at compile-time. var纯粹在编译时使用。 The compiler works out the type, replaces it, and the bytecode is the same as if it had never been used.编译器计算出类型,替换它,字节码就像从未使用过一样。 There is no functional difference between之间没有功能差异

var foo = new StringBuilder();

and

StringBuilder foo = new StringBuilder();

It is purely a cosmetic difference which makes the language more expressive.这纯粹是一种表面差异,使语言更具表现力。


A note about var 's status关于var状态的说明

Java language designers are always very careful when adding new features to not break backwards compatibility, and so var has somewhat special status. Java 语言设计者在添加新特性时总是非常小心,以免破坏向后兼容性,因此var具有某种特殊的地位。 It is not a keyword, because having keyword status would be overly restrictive.它不是关键字,因为具有关键字状态会过于严格。 Keywords cannot be used as identifiers, for example;例如,关键字不能用作标识符; I cannot have a method called if because if is a keyword.我无法调用if方法if因为if是关键字。

var is, as your quote states, a "reserved type name".正如您的引述所说, var是“保留类型名称”。 This sounds complex at first but it is actually very descriptive of var 's status.乍一看这听起来很复杂,但实际上它非常描述了var的状态。 It is the name of a type that has been reserved by Java.它是 Java 保留的类型的名称。 You cannot name your types - classes, interfaces, enumerations - var , because that would introduce an ambiguity.您不能命名您的类型 - 类、接口、枚举 - var ,因为这会引入歧义。

You are still free to use the word "var" in every other context - method names, variable identifiers, etc.您仍然可以在所有其他上下文中自由使用“var”一词 - 方法名称、变量标识符等。

By having this status, the designers have maximized backwards compatibility (short of not adding the feature at all!).通过拥有这种状态,设计人员最大限度地向后兼容(根本不添加功能!)。 Unless you had a class called lowercase var -- and firstly what are you doing choosing these terrible names, and secondly why didn't you at least follow the naming convention and call it Var ?除非你有一个叫做小写var的类——首先你在做什么选择这些可怕的名字,其次你为什么不至少遵循命名约定并将它称为Var -- then you're protected from any breaking changes. -- 然后您就可以免受任何重大更改的影响。

There's a whole question about this here: What type of token exactly is "var" in Java 10?这里有一个完整的问题: Java 10 中的“var”究竟是什么类型的令牌?


Good feature, right?功能不错吧? It definitely is but it important not to simply start using it everywhere just because you can.这绝对是,但重要的是不要仅仅因为可以就开始在任何地方使用它。 Stuart Marks, one of the JDK developers, has some excellent style guidelines which I recommend that you read. Stuart Marks 是 JDK 开发人员之一,他有一些出色的样式指南,我建议您阅读这些指南

My rule of thumb is that if the type is not specified on the same line (as it is in the above examples) then I do not use var .我的经验法则是,如果未在同一行中指定类型(如上述示例中所示),则我不使用var The compiler is clever enough to infer the type from the result of any valid expression, so the following is perfectly valid:编译器足够聪明,可以从任何有效表达式的结果中推断出类型,因此以下内容完全有效:

var foo = bar();

However, without looking at the method signature, it is not immediately obvious what the type of the variable will be inferred to be.但是,如果不查看方法签名,则推断出变量的类型并不是很明显。 There is no ambiguity for the the compiler but it is less clear for the human who's reading it.编译器没有歧义,但阅读它的人不太清楚。 In such a case, we have sacrificed readability for brevity.在这种情况下,我们为了简洁而牺牲了可读性。


Further reading进一步阅读

var is something that is already in C#. var是 C# 中已经存在的东西。 Basically, instead of declaring a variable type, it assumes its type from what it is being set to.基本上,它不是声明一个变量类型,而是根据它被设置的类型来假设它的类型。 For instance:例如:

var myString = "Hello world"

Because you are setting it to a value in quotes, it assumes it is a String , rather than having to specify like:因为您将它设置为引号中的值,所以它假定它是一个String ,而不必指定如下:

String myString = "Hello world"

I was reading about the new features released in Java 10 and I found this:我正在阅读有关Java 10中发布的新功能的信息,我发现了这一点:

Java 10 introduced var as a reserve type name to reduce verbosity. Java 10引入了var作为保留类型名称,以减少冗长。 It can be used as a variable, method, and package name, but we cannot use it as a class or interface name.它可以用作变量,方法和程序包名称,但是我们不能将其用作类或接口名称。

Is var similar to the var keyword in JavaScript? var是否类似于JavaScript中的var关键字? What exactly are the similarities and the differences between Java's var and JavaScript's var ? Java的var和JavaScript的var之间到底有什么相似和不同?

Var is a new Keyword that was introduced in Java 10 . VarJava 10中引入的新关键字。 The behaviors are almost the same as JavaScript.行为几乎与 JavaScript 相同。 See below for what we can and cannot with the Var Keyword in Java.请参阅下文,了解我们可以使用 Java 中的 Var 关键字做什么和不可以做什么。

Can

  • Declare any datatype with the var keyword使用 var 关键字声明任何数据类型
  • Be used in a local variable declaration在局部变量声明中使用

CanNot不能

  • Be used in an instance and global variable declaration在实例和全局变量声明中使用
  • Be used as a Generic type用作泛型类型
  • Be used with the generic type与泛型类型一起使用
  • Be used without explicit initialization无需显式初始化即可使用
  • Be used with Lambda Expression与 Lambda 表达式一起使用
  • Be used for method parameters and return type用于方法参数和返回类型

Updates: var supports Generic Type and also Lambda Expressions from Java 11.更新: var支持 Java 11 中的泛型类型和 Lambda 表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM