为什么Java中的变量名不能与关键字同名?
在我所知道的大多数编程语言中,不能声明名称也是关键字的变量 例如,在Java中:为什么Java中的变量名不能与关键字同名?,java,parsing,syntax,compiler-construction,Java,Parsing,Syntax,Compiler Construction,在我所知道的大多数编程语言中,不能声明名称也是关键字的变量 例如,在Java中: public class SomeClass { Class<?> clazz = Integer.class; // OK. Class<?> class = Integer.class; // Compilation error. } 公共类SomeClass { Class clazz=Integer.Class;//确定。 Class=Integer.Class;/
public class SomeClass
{
Class<?> clazz = Integer.class; // OK.
Class<?> class = Integer.class; // Compilation error.
}
公共类SomeClass
{
Class clazz=Integer.Class;//确定。
Class=Integer.Class;//编译错误。
}
但是很容易弄清楚什么是什么。阅读它的人不会混淆变量名和类声明,编译器也不会混淆它
如果我们谈论Java编程语言的话,变量名如“for”、“extends”、“goto”或其他任何名称也是一样的
我们有这个限制的原因是什么?它允许词法分析器在不必消除上下文歧义的情况下对符号进行分类-这反过来又允许根据语法规则解析语言,而不需要了解编译过程的其他(“更高”)部分,包括类型分析
作为一个并发症(和歧义)的例子,删除这样的区别会增加解析,请考虑以下几点。在标准的Java规则下,它声明并分配一个变量——对于如何解析它没有任何歧义
final Foo x = 2; // roughly: <keyword> <identifier> <identifier> = <value>
但如果final是“final type”,则读数可能是:
final Foo = 2; // hypothetical: <identifier> <identifier> = <value>
final Foo=2;//假设:=
对来源的哪种解释是正确的
由于单独编译,Java使得这个问题更难回答。在命名空间中添加(或意外导入)新的“final type”是否应该改变代码的解析方式?报告一个未解析的符号是一回事——根据这种解析改变语法的解析方式是另一回事
这类问题只是通过明确区分保留字来绕过
可以说,可以使用特殊的产品动态地更改关键字的识别(某些语言允许可控的运算符优先级),但主流语言中没有这样做,Java肯定不支持这样做。至少,它需要额外的语法,并增加了系统的复杂性,但没有带来足够的好处 我见过的解决这类问题的最“干净”的方法是C#,它允许在保留字前面加一个前缀,并删除特殊含义,例如
class@class{float@int=2;}
——尽管这样做应该很少,而且
现在,Java中保留的一些单词可以“仅在上下文中保留”,例如extends
。这在SQL中一直可见;有保留字(例如,超过
),然后是在给定语句结构中只有特殊意义的字(例如,行号
)。但更容易说保留就是保留,去选别的吧
除了像LISP方言这样一种非常容易解析的语言,它有效地将每一个裸词都视为标识符之外,关键字以及与标识符的区别在语言语法中非常普遍
我们有这个限制的原因是什么
一般来说,有两个原因:
- 正如你在你的问题中所指出的那样:这对人类读者来说是非常令人困惑的。一种设计混乱的编程语言,作为一种实用的编程语言,不会有太大的吸引力
- 如果标识符可以与关键字相同,那么编写该语言的正式语法就困难得多。(当然,带有消歧规则的语法不能用BNF/EBNF或类似的语言表示。)这意味着为这种语言编写解析器要复杂得多
主流编程语言中有一个有趣的(半)反例。在FORTRAN的早期版本中,标识符中的空格并不重要。因此
I J = 1
及
意思是一样的。这很酷(取决于你的“品味”…)。但比较这两个:
DO 20 I = 10, 1, -2
对
DO 20 I = 10
一个是赋值,另一个是“DO循环”语句。作为一名读者,你会注意到这一点吗?你说得不太对。关键字是在语言语法中有意义的词,保留词是不允许用作标识符的词。在Java中,它们基本上是相同的,但是'true'和'goto'是保留字,而不是关键字('true'是一个文本,不使用'goto') 在语言中保留关键字的主要原因是为了简化语法分析和避免歧义。例如,如果
return
可能是一种方法,这意味着什么
return(1);
在我看来,Java已经走得太远了。有一些关键词只有在没有歧义的特定语境中才有意义。也许避免读者产生混淆是有好处的,但我把它归因于编译作者的习惯。还有一些其他语言的关键词和/或保留词要少得多,而且效果很好。评论不错,听起来像是一个答案。那么编译速度是不是原因呢?它只是一种语言设计选择。Java采用了明确、清晰的语法,因为这使代码更易于阅读。当然,其他语言以可读性为代价做出了不同的选择,不仅仅是速度。它简化了编译器代码并提高了可靠性。此外,必须存在病毒感染的病例
DO 20 I = 10
return(1);