我正在阅读Java 10中发布的新功能,我发现“Java 10引入var
作为保留类型名称以减少冗长。它可以用作变量,方法和包名称,但是我们不能将它用作类或接口名称。“
阅读本文后,我有点困惑,所以var
与Javascript中的var
关键字类似? Java var
和Javascript var
之间的相似点和区别究竟是什么?
答案 0 :(得分:3)
var
在两种语言中在概念上都有相似的目的,但是有重要的区别。
JavaScript是dynamically typed language。变量没有类型信息。它对其包含的内容没有任何限制。它只是一个值的持有人,该值可以是任何类型。
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
寻求reduce the amount of repeated declarations。像之前的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
是“保留类型名称”。乍一看听起来很复杂,但实际上是对var
状态的描述。它是Java保留的类型的名称。您无法命名类型-类,接口,枚举-var
,因为那样会引起歧义。
您仍然可以在所有其他上下文中自由使用“ var”一词-方法名称,变量标识符等。
通过具有这种状态,设计人员可以最大程度地向后兼容(根本不添加任何功能!)。除非您有一个名为小写var
的类-首先,您要如何选择这些可怕的名称,其次,您为什么不至少遵循命名约定并将其命名为Var
? -那么您就可以免受任何重大更改。
这里有一个完整的问题:What type of token exactly is "var" in Java 10?
好的功能,对不对?绝对是重要的,但重要的是不要仅仅因为可以就开始在任何地方使用它。 JDK开发人员之一Stuart Marks有一些出色的style guidelines,我建议您阅读。
我的经验法则是,如果未在同一行上指定类型(如上述示例中所示),那么我将不使用var
。编译器足够聪明,可以从任何有效表达式的结果推断出类型,因此以下内容完全有效:
var foo = bar();
但是,在不查看方法签名的情况下,并不能立即清楚地推断出变量的类型是什么。编译器没有歧义,但是对于正在阅读它的人来说并不清楚。在这种情况下,为了简洁起见,我们牺牲了可读性。
进一步阅读
答案 1 :(得分:0)
var
已经存在于C#中。基本上,它不是声明一个变量类型,而是根据它的设置来假定它的类型。例如:
var myString = "Hello world"
因为您将其设置为引号中的值,所以它假设它是String
,而不是必须指定:
String myString = "Hello world"
答案 2 :(得分:0)
总结了在Java代码中使用var的各种规则:
在构造函数,方法或初始化程序块中,var用作局部变量。
不能在构造函数参数,方法参数, 实例变量或类变量。
变量总是在声明它的同一行(或语句)上初始化。
var的值可以更改,但类型不能更改。
不能使用无类型的空值初始化var。
在多变量声明中不允许使用var。 如:
var a = 2,b = 3; //无法编译
var是保留的类型名称,而不是保留的单词,这意味着它可以用作标识符,但不能用作类,接口或枚举名称。
我们可以这样做(但为了代码的可读性不建议这样做):
package var;
public class Var {
public void var() {
var var = "var";
}
public void Var() {
Var var = new Var();
}
}
但是我们不能这样做:
public class var { // DOES NOT COMPILE
public var() {
}
}