What type of token exactly is “var” in Java 10?
在上一期Heinz Kabutz的新闻通讯#255 Java 10:推断的局部变量中,显示var不是Java 10中的保留字,因为您还可以使用var作为标识符:
1 2 3
| public class Java10 {
var var = 42; // <-- this works
} |
但是,您不能使用ie assert作为标识符,如var assert = 2,因为assert是保留字。
正如在链接的时事通讯中所说的那样,var不是保留字的事实是好消息,因为这允许使用var作为标识符的旧版Java的代码在Java 10中编译而没有问题。
那么,什么是var呢?它既不是显式类型也不是语言的保留字,因此它被允许作为标识符,但是当它用于在Java 10中声明局部变量时它确实具有特殊含义。我们究竟在一个上下文中调用它局部变量声明?
此外,除了支持向后兼容性(通过允许包含var的旧代码作为标识符进行编译),var不是保留字还有其他优点吗?
-
我知道这是为了向后兼容,但我认为使用var var只会导致新一代的混乱。
-
@FedericoPeraltaSchaffner var var = 42或Integer var = 42的字节代码完全相同;它只适用于编译器,因此它是一个类型名称。请注意,这与Integer Integer = 42没有什么不同(upvote重新打开,真的想让这个也成为一个答案)
-
嗨@Eugene!不完全是,你不能拥有class var {},而你可以拥有class Integer {}。但字节代码是相同的(如果你这样说)。
-
@FedericoPeraltaSchaffner好点!
-
@BrianGoetz感谢您抽出宝贵时间对此问题发表评论。由于最受欢迎和接受的答案声称"var"是一个"上下文敏感的关键字",你在其他评论中说过,情况并非如此,你是否愿意写一个规范的答案,澄清正确的答案是什么以及如何"保留类型标识符"与C ++中的"上下文敏感关键字"不同?
-
@BrianGoetz特别是自JEP-286以来,已接受的答案引用,于今天3/4/2018更新,以反映语言从"上下文敏感关键字"到"保留类型标识符"的变化。
-
我编辑了规范的答案。
-
@bhspencer更正;它是从两者的分离(反映项目一开始的选项)更新为"保留类型标识符"(反映最终结果。)JEP是活文件;设计在开始和结束之间发展是很常见的,理想情况下我们会更新JEP以反映现实。
-
@BrianGoetz感谢您的更新。你能说一下为什么令牌"var"不被认为是"受限制的关键字",比如"模块"。
-
@bhspencer因为受限类型标识符是一种更简单,更简洁的方法来指定和实现所需的结果。我们可以使用受限制的关键字,但它在语法和规范中会更具侵入性,因为没有增量收益。
-
@BrianGoetz我不清楚语法如何在两种方式上都不同。我必须遗漏一些东西,但这听起来像是一个实现细节,而不是概念上的差异。我期待在JLS 10发布时阅读它,我想这将为我清除它。
-
@bhspencer为什么不问一个链接到这个问题的特定问题,关于保留类型标识符和上下文相关关键字之间的概念差异,以java 10和var为背景?
-
该功能的规范草案已公开发布一年;最终版本(在集成到主规范之前)在这里:bugs.openjdk.java.net/secure/attachment/72914/… (链接自bugs.openjdk.java.net/browse/JDK-8151553)。
-
@BrianGoetz引用该草案"字符序列var通常被视为一个标识符,但在某些特殊情况下,就好像它是一个关键字一样。"这确实听起来像一个"上下文敏感的关键字"。
-
@bhspencer是的,下一句话给出了受限制的关键字列表。并且var不在该列表中。您引用的句子包含在第3.9节("关键字")中,正是为了清楚地表明虽然它有时可能像一个一样,但它不是关键词,不受限制。 (如果我们在本节中遗漏了提及,像你这样的人总会问"但是var"。)
-
@BrianGoetz我继续问这个单独的问题stackoverflow.com/questions/49102553/…
根据JEP-286:局部变量类型推断,var是
not a keyword; instead it is a reserved type name.
(早期版本的JEP为实现保留类型名称或上下文相关关键字留下了空间;最终选择了前一个路径。)
因为它不是"保留关键字",所以仍然可以在变量名(和包名)中使用它,但不能在类或接口名中使用它。
我认为不使var保留关键字的最大原因是与旧源代码的向后兼容性。
-
我知道你在这里引用了来源,但句子在逻辑上被打破了。说些什么不仅仅是一个关键词继续说它是一种特殊类型的关键词。考虑看一棵苹果树和一位植物学家说"哦,那不是一棵苹果树。"
-
是的,"上下文相关的关键字"可能有点令人困惑。 JLS for Java 10尚未发布,但官方术语可能是"保留类型名称"。
-
"上下文敏感的关键字"很好。它是C ++社区已经使用的术语:"上下文敏感的关键字是仅在特定上下文中被识别的语言元素。在特定上下文之外,上下文敏感的关键字可以是用户定义的符号。"
-
我只是对JLS中的草率语言提出异议。特别是如果它最终在一个公认的SO答案中被引用,我们将会有多年的人争辩说这不是一个明显错误的关键词。
-
@bhspencer在3.9中明确定义了一个关键字。上下文相关的关键字是另一回事。这里没有"破碎"。
-
JLS:3.9提供了一个非常清晰的关键字定义:您不能使用一个作为标识符。所以在这个意义上,var确实不是关键字。
-
@MickMnemonic var不是关键字,除非它是,并且"when"由上下文定义。这就是将"上下文敏感"限制应用于名词关键字的含义。这意味着var有时是一个关键字。
-
顺便说说。上下文敏感关键字对Java来说并不陌生。它们已经在Java 9中。例如,您可以声明module module。
-
@BrianGoetz你能解释一下"上下文敏感关键字"和"保留类型标识符"之间的区别吗?
-
@ZhekaKozlov Java 9 JLS在定义"模块"时使用短语"受限制的关键字"。我认为你是对的,但就所有意图和目的而言,"受限制的关键字"看起来是"上下文敏感关键字"的同义词。我很好奇为什么Goetz等人。决定这个词对var来说是不够的。
-
上下文敏感关键字是在特定产品中被识别为具有语法含义的字符序列,但在其他方面被视为普通标识符。 (这通常在编译的解析阶段进行管理。)保留类型标识符是不能用作类型名称的标识符(这在编译的归属阶段处理。)
-
@BrianGoetz bhspencer开启了一个新问题Java 10中"限制关键字"和"保留类型标识符"之间的概念差异是什么?这可能是该问题的良好答案的一部分。
var is a reserved type name var is not a keyword, It’s a reserved type
name.
我们可以创建一个名为"var"的变量。
你可以在这里阅读更多细节。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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 |