What is var in Java 10?

后端 未结 3 787
不思量自难忘°
不思量自难忘° 2021-01-29 08:44

I was reading about the new features released in Java 10 and I found

Java 10 introduced var as a reserve type name to reduce verbosity. It

相关标签:
3条回答
  • 2021-01-29 09:14

    var serves a somewhat conceptually similar purpose in both languages, but there are important differences.

    JavaScript is a dynamically typed language. 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. 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 objectVariable = "hello";
    FieldTagTestsVisitorComparator enterpriseVariable = new FieldTagTestsVisitorComparator();
    

    In JavaScript, I can very concisely write

    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. In my example above, I've declared FieldTagTestsVisitorComparator twice on the same exact line. What value is that adding? I've just repeated myself.

    var in Java seeks to reduce the amount of repeated declarations. 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. 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

    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.

    This fundamentally differs from JavaScript because although I have not specified the type, a type is still present. 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. 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

    Java language designers are always very careful when adding new features to not break backwards compatibility, and so var has somewhat special status. 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.

    var is, as your quote states, a "reserved type name". This sounds complex at first but it is actually very descriptive of var's status. It is the name of a type that has been reserved by Java. You cannot name your types - classes, interfaces, enumerations - var, because that would introduce an ambiguity.

    You are still free to use the word "var" in every other context - method names, variable identifiers, etc.

    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? -- 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?


    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.

    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. 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

    • JEP 286: Local-Variable Type Inference
    • FAQ for JEP 286 (Local Variable Type Inference)
    0 讨论(0)
  • 2021-01-29 09:31

    var is something that is already in 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 myString = "Hello world"
    
    0 讨论(0)
  • 2021-01-29 09:40

    Summarizing the various rules for using var in your Java code:

    1. A var is used as a local variable in a constructor, method, or initializer block.

    2. A var cannot be used in constructor parameters, method parameters, instance variables, or class variables.

    3. A var is always initialized on the same line (or statement) where it is declared.

    4. The value of a var can change, but the type cannot.

    5. A var cannot be initialized with a null value without a type.

    6. A var is not permitted in a multiple-variable declaration. as in:

      var a = 2, b = 3; // DOES NOT COMPILE

    7. A var is a reserved type name but not a reserved word, meaning it can be used as an identifier except as a class, interface, or enum name.

    We can do this (but not recommended for readability of code):

    package var;
    public class Var {
    
      public void var() {
        var var = "var";
      }
    
      public void Var() {
        Var var = new Var();
      }
    }
    

    but we cannot do this:

    public class var { // DOES NOT COMPILE
    
      public var() {
      }
    }
    
    0 讨论(0)
提交回复
热议问题