21

In the last issue of Heinz Kabutz's newsletter, #255 Java 10: Inferred Local Variables, it is shown that var is not a reserved word in Java 10, because you can also use var as an identifier:

public class Java10 {
    var var = 42; // <-- this works
}

However, you cannot use i.e. assert as an identifier, as in var assert = 2, because assert is a reserved word.

As it's told in the linked newsletter, the fact that var is not a reserved word is good news, because this allows code from previous versions of Java that uses var as an identifier to compile without problems in Java 10.

So, what's var then? It's neither an explicit type nor a reserved word of the language, so it's allowed to be an identifier, however it does have a special meaning when used to declare a local variable in Java 10. What exactly do we call it in the context of a local variable declaration?

Additionally, apart from supporting backwards compatibility (by allowing older code that contains var as an identifier to compile), are there other advantages to var not being a reserved word?

Boann
  • 48,794
  • 16
  • 117
  • 146
fps
  • 33,623
  • 8
  • 55
  • 110
  • 1
    I understand that this was done for backward compatibility but I think using var var will just cause a confusion for new generation. – Aniket Sahrawat Mar 04 '18 at 04:03
  • 2
    @FedericoPeraltaSchaffner The byte code with `var var = 42` or `Integer var = 42` is exactly the same; it's just for the compiler here, so it's a type name. Notice that this is not very different than `Integer Integer = 42` (upvote to re-open, really wanted to make this one an answer too) – Eugene Mar 04 '18 at 11:03
  • 1
    Hi @Eugene! Not exactly, you can't have a `class var {}`, while you can have a `class Integer {}`. The byte code is the same (if you say so), though. – fps Mar 04 '18 at 13:55
  • @FedericoPeraltaSchaffner good point! – Eugene Mar 04 '18 at 13:56
  • @BrianGoetz I appreciate you taking the time to comment on this question. Since the most upvoted and accepted answer claims "var" is a "context sensitive keyword" and you have said in other comments that this is not the case would you be willing to write a canonical answer that clarifies what what the correct answer is and how "reserved type identifier" differs from the "context sensitive keyword" in C++? – bhspencer Mar 04 '18 at 23:38
  • 1
    @BrianGoetz especially since the JEP-286, that the accepted answer quotes from, was updated today 3/4/2018 to reflect the change of language from "context sensitive keyword" to "reserved type identifier". – bhspencer Mar 04 '18 at 23:46
  • 2
    I've edited the canonical answer. – Brian Goetz Mar 05 '18 at 00:47
  • 2
    @bhspencer Correction; it was updated from the disjunction of the two (reflecting the options out the outset of the project) to "reserved type identifier" (reflecting the final outcome.) JEPs are living documents; it is common for the design to evolve between start and end, and ideally we update the JEP to reflect reality as we go. – Brian Goetz Mar 05 '18 at 00:50
  • 1
    @BrianGoetz thanks for the update. Could you say anything about why the token "var" is not considered a "restricted keyword" like "module". – bhspencer Mar 05 '18 at 01:00
  • 2
    @bhspencer Because restricted type identifiers were a simpler and cleaner way to specify and implement the desired result. We could have used a restricted keyword, but it would have been more intrusive in the grammar and specification, for no incremental benefit. – Brian Goetz Mar 05 '18 at 01:03
  • 1
    @BrianGoetz It is not clear to me how the grammar would be different either way. I must me missing something but It sounds like an implementation detail rather than a conceptual difference. I look forward to reading the JLS 10 when it comes out, I imagine that will clear it up for me. – bhspencer Mar 05 '18 at 01:36
  • @bhspencer Why don't you ask a specific question that links to this one, about the conceptual difference between a reserved type identifier and a context-sensitive keyword, with java 10 and `var` as a background? – fps Mar 05 '18 at 01:42
  • 2
    The specification drafts for this features has been available publicly for a year; final version (prior to integration into the master spec) is here: https://bugs.openjdk.java.net/secure/attachment/72914/local-var-inference.html (linked from https://bugs.openjdk.java.net/browse/JDK-8151553). – Brian Goetz Mar 05 '18 at 02:05
  • @BrianGoetz to quote that draft "The character sequence var is generally treated as an identifier, but in certain special cases acts as if it were a keyword instead." That sure does sound like a "context sensitive keyword". – bhspencer Mar 05 '18 at 02:24
  • 2
    @bhspencer Yes, and the very next sentence gives the list of _restricted keywords_. And `var` is not on that list. The sentence you cite was included in section 3.9 ("Keywords") precisely to make it clear that while it may sometimes _act_ like one, it is not a keyword, restricted or not. (If we'd left out a mention in this section, someone like you would invariably have asked "but what about `var`".) – Brian Goetz Mar 05 '18 at 02:33
  • 1
    @BrianGoetz I went ahead and asked this as a separate question https://stackoverflow.com/questions/49102553/what-is-the-conceptual-difference-between-a-restricted-keyword-and-reserved-t?noredirect=1#comment85210428_49102553 – bhspencer Mar 05 '18 at 02:35

2 Answers2

22

According to JEP-286: Local-Variable Type Inference, var is

not a keyword; instead it is a reserved type name.

(Earlier versions of the JEP left room for implementing either as a reserved type name or as a context-sensitive keyword; the former path was ultimately chosen.)

Because it's not a "reserved keyword", it is possible to still use it in variable names (and package names), but not in class or interface names.

I would think the biggest reason for not making var a reserved keyword is backwards compatibility with old source code.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
Mick Mnemonic
  • 7,808
  • 2
  • 26
  • 30
  • I realize you are quoting from source here but the sentence is logically broken. To say something is not a keyword only to go on and say it is a special type of keyword. Consider looking at an apple tree and a botanist saying "oh that is not a tree that is an apple tree." – bhspencer Mar 03 '18 at 21:16
  • Yes, "context-sensitive keyword" is maybe a bit confusing. The JLS for Java 10 is not published yet, but the official term could be "reserved type name". – Mick Mnemonic Mar 03 '18 at 21:23
  • 1
    "context-sensitive keyword" is fine. It is a term of art already used by the C++ community: "Context-sensitive keywords are language elements that are recognized only in specific contexts. Outside the specific context, a context-sensitive keyword can be a user-defined symbol." – bhspencer Mar 03 '18 at 21:24
  • I just take issue with the sloppy language in the JLS. Especially if it ends up being quoted in an accepted SO answer we will have years of people arguing that is it not a keyword which is patently false. – bhspencer Mar 03 '18 at 21:27
  • 3
    @bhspencer A *keyword* is explicitly defined in 3.9. A *context-sensitive keyword* is something else. There's no "broken" here. – chrylis -cautiouslyoptimistic- Mar 03 '18 at 21:35
  • 5
    [JLS:3.9](https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.9) provides a really clear definition of _keyword_: you cannot use one as an identifier. So in this sense, `var` really isn't a keyword. – Mick Mnemonic Mar 03 '18 at 21:35
  • @MickMnemonic var isn't a keyword except when it is, and that "when" is defined by the context. That is literally what it means to apply a the restriction "context-sensitive" to the noun keyword. It means var is sometimes a keyword. – bhspencer Mar 03 '18 at 23:59
  • 3
    By the way. Context sensitive keywords are not new to Java. They were already in Java 9. For example, you can declare `module module`. – ZhekaKozlov Mar 04 '18 at 02:52
  • @BrianGoetz can you explain the difference between "context-sensitive keywords" and "reserved type identifiers"? – bhspencer Mar 04 '18 at 23:35
  • @ZhekaKozlov the Java 9 JLS uses the phrase "restricted keywords" when defining "module". I think you are right though, to all intents and purposes a "restricted keyword" looks to be a synonym to "context sensitive keyword". I am curious why Goetz et al. decided this term was insufficient for var. – bhspencer Mar 05 '18 at 00:13
  • 7
    A context sensitive keyword is a character sequence that is recognized as having syntactic meaning in specific productions, but is otherwise treated as an ordinary identifier. (This is typically managed in the parsing stage of compilation.) A reserved type identifier is an an identifier that may not be used as the name of a type (this is handled in the attribution stage of compilation.) – Brian Goetz Mar 05 '18 at 00:54
  • 2
    @BrianGoetz bhspencer has opened a new question [What is the conceptual difference between a “restricted keyword” and “reserved type identifier” in Java 10?](https://stackoverflow.com/questions/49102553/what-is-the-conceptual-difference-between-a-restricted-keyword-and-reserved-t) This may be part of a good answer to that question. – Erwin Bolwidt Mar 05 '18 at 02:21
7

var is a reserved type name var is not a keyword, It’s a reserved type name.

We can create a variable named “var”.

you can read here for more details.

var var = 5; // syntactically correct
// var is the name of the variable
“var” as a method name is allowed.

public static void var() { // syntactically correct 
}
“var” as a package name is allowed.

package var; // syntactically correct
“var” cannot be used as the name of a class or interface.
class var{ } // Compile Error
LocalTypeInference.java:45: error: 'var' not allowed here
class var{
      ^
  as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
1 error

interface var{ } // Compile Error

var author = null; // Null cannot be inferred to a type 
LocalTypeInference.java:47: error: cannot infer type for local variable author
                var author = null;
                    ^
  (variable initializer is 'null')
1 error
Roushan
  • 4,074
  • 3
  • 21
  • 38