为什么Java中的变量名称不能与关键字具有相同的名称?

时间:2014-08-17 01:50:12

标签: java parsing syntax compiler-construction

在大多数编程语言中,我知道你不能声明一个名字也是关键词的变量。

例如在Java中:

public class SomeClass
{
    Class<?> clazz = Integer.class; // OK.
    Class<?> class = Integer.class; // Compilation error.
}

但是很容易弄明白什么是什么。阅读它的人不会将变量名称与类声明混淆,编译器也很可能不会混淆它。

如果我们谈论Java编程语言,关于变量名称的相同内容,如'for','extends','goto'或来自Java key words的任何内容。

我们有这个限制的原因是什么?

3 个答案:

答案 0 :(得分:2)

  

我们有这个限制的原因是什么?

一般有两个原因:

  • 正如您在问题中所指出的那样:对于人类读者而言,这将是非常混乱的。一种令设计混乱的编程语言不会像实用编程语言那样受到重视。

  • 如果标识符可以与关键字相同,那么为该语言编写正式语法会更加困难。 (当然,像歧义消除规则这样的语法不能用BNF / EBNF或类似的方式表达。)这意味着为这种语言编写解析器会复杂得多。

无论如何,虽然这些原因都不是一个完整的&#34;显示塞子&#34;,但它们足以让大多数人尝试新的编程语言设计/实现来拒绝这个想法。

当然是真正的原因,你(几乎)从未看到可以将关键字用作标识符的语言。编程语言设计师几乎总是拒绝这个想法......

(在Java的情况下,有意识地努力使人们可以使用C语言的C语言.C不支持这个。这可能是第三个原因......如果他们是寻找一个。)


主流编程语言中有一个有趣的(半)计数器示例。在早期版本的FORTRAN中,标识符中的空格并不重要。因此

    I J = 1

    IJ = 1

意味着同样的事情。这很酷(取决于你的&#34;味道&#34; ......)。但比较这两个:

    DO 20 I = 10, 1, -2

    DO 20 I = 10

一个是作业,但另一个是&#34; DO循环&#34;声明。作为读者,您会注意到这一点吗?

答案 1 :(得分:1)

它允许词法分析器对符号进行分类而不必消除歧义上下文 - 这反过来允许根据语法规则解析语言,而不需要需要有关其他语言的知识(&#34;更高&#34; )编译过程的一部分,包括类型分析。

作为并发症(和模糊性)的一个例子,去除这种区别会增加解析,请考虑以下内容。在标准的Java规则下,它声明并分配一个变量 - 它的解析方式没有歧义。

final Foo x = 2;   // roughly: <keyword> <identifier> <identifier> = <value>

现在,在没有严格关键字区分的假设语言中,想象以下内容,其中final 可能是声明的类型;现在有两个可能的读数。第一个是当final 一个类型并且存在标准读数时:

final Foo = 2;     // roughly: <keyword> <identifier> ?error? = <value>

但如果最终的 a&#34;最终类型&#34;,那么阅读可能是:

final Foo = 2;     // hypothetical: <identifier> <identifier> = <value>

对来源的哪种解释是正确的?

由于单独的编译,Java使得这个问题更难回答。应该添加一个新的&#34;最终类型&#34; in(或意外导入)命名空间现在改变了代码的解析方式?报告未解析的符号是一回事 - 改变基于这种分辨率解析语法的方式是另一回事。

这些问题只是通过明确区分保留字而被绕过。


可以说,可以有一些特殊的作品来动态地改变关键词的识别(某些语言允许可控制的运算符优先级),但这是在主流语言中完成的,并且是大多数情况下,Java中不支持 。至少它需要额外的语法,并增加了系统的复杂性,但效益不足。

最干净&#34;清洁&#34;方法我已经看到这样的问题在C#中,它允许一个前缀保留字并删除class @class { float @int = 2; }之类的特殊含义 - 虽然这种情况应该很少进行,并且ick!

现在,Java中保留的一些单词只能在上下文&#34;中保留,例如extends。这种情况一直在SQL中看到;有保留字(例如OVER),然后是在给定语句结构中只有特殊含义的字(例如ROW_NUMBER)。但保留更容易保留,去选择别的东西。

除了像LISP方言这样非常易于解析的语言,它有效地将每个裸字视为标识符,关键字和标识符的区别在语言语法中非常普遍。

答案 2 :(得分:1)

你不太对劲。关键词是在语言的语法中有意义的词,保留词是您不允许用作标识符的词。在Java中,它们大多是相同的,但是'true'和'goto'是保留字而不是关键字('true'是文字而不使用'goto')。

在语言保留字中制作关键词的主要原因是为了简化解析并避免歧义。例如,如果return可能是一种方法,这意味着什么?

return(1);

在我看来,Java已经走得太远了。有些关键词只在特定的语境中有意义,在这种语境中不存在歧义。也许有利于避免读者的混淆,但我把它归结为编译器编写者的习惯习惯。还有其他语言的关键词和/或保留词少得多,工作得很好。