什么是Java 10中的var

时间:2018-04-03 18:36:16

标签: java-10

我正在阅读Java 10中发布的新功能,我发现“Java 10引入var作为保留类型名称以减少冗长。它可以用作变量,方法和包名称,但是我们不能将它用作类或接口名称。“ 阅读本文后,我有点困惑,所以var与Javascript中的var关键字类似? Java var和Javascript var之间的相似点和区别究竟是什么?

3 个答案:

答案 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。那增加了什么价值?我只是重复我自己。

Java中的

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的各种规则:

  1. 在构造函数,方法或初始化程序块中,var用作局部变量。

  2. 不能在构造函数参数,方法参数, 实例变量或类变量。

  3. 变量总是在声明它的同一行(或语句)上初始化。

  4. var的值可以更改,但类型不能更改。

  5. 不能使用无类型的空值初始化var。

  6. 在多变量声明中不允许使用var。 如:

    var a = 2,b = 3; //无法编译

  7. 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() {
  }
}