为什么标识符不能以数字开头?

时间:2009-10-29 17:19:36

标签: java

为什么在java中(我不知道任何其他编程语言)标识符不能以数字开头,为什么以下声明也不允许?

int :b;
int -d;  
int e#;
int .f;
int 7g;

7 个答案:

答案 0 :(得分:40)

一般来说,你提出这种限制有两个原因:

  1. 以电子方式解析是一件痛苦的事。
  2. 解析人类是一种痛苦。
  3. 请考虑以下代码段:

    int d, -d;
    d = 3;
    -d = 2;
    d = -d;
    

    如果-d是合法标识符,那么d最后会得到哪个值? -3还是2?这是不明确的。

    还要考虑:

    int 2e10f, f;
    2e10f = 20;
    f = 2e10f;
    

    f最终有什么价值?这也很模糊。

    此外,无论如何阅读都是一种痛苦。如果有人声明2ex10,这是200万错误或变量名吗?

    确保标识符以字母开头意味着它们可以与之冲突的唯一语言项是保留关键字。

答案 1 :(得分:7)

这是因为Java语言规范的section 3.8这样说。

  

标识符是无限长度的   Java字母和Java的序列   数字,第一个必须是a   Java信。标识符不能有   相同的拼写(Unicode字符   序列)作为关键字(§3.9),布尔值   文字(§3.10.3)或空文字   (§3.10.7)。

至于为什么做出这个决定:可能是因为这简化了解析,避免了歧义语法,允许在更高版本的语言和/或历史原因中引入特殊语法(即因为大多数其他语言具有相同的限制类似限制)。请注意,-d的示例示例特别明确:

int -d = 7;
System.out.println("Some number: " + (8 + -d));

减号是标识符的第一部分,还是一元减号?

此外,如果您同时将-dd作为变量,那么它将完全不明确:

int -d = 7;
int d = 2;
System.out.println("Some number: " + (8 + -d));

结果是15还是6?

答案 2 :(得分:3)

我不确切知道,但我认为这是因为数字用于表示文字值,因此当编译器找到以数字开头的标记时,它知道它正在处理文字。如果标识符可以以数字开头,则编译器需要使用预先查找令牌中的下一个字符,以确定它是标识符还是文字。

答案 3 :(得分:2)

这种事情几乎不允许任何语言(我现在想不到),主要是为了防止混淆。

您的示例-d是一个很好的例子。编译器如何知道你的意思是“名为-d的变量”还是“变量d中数字的负数”?既然它无法分辨(或者更糟糕的是,它可以所以你无法确定在没有读取文件的其余部分的情况下键入它时会发生什么),这是不允许的。

示例7g是一样的。您可以通过在末尾添加字母来指定数字作为特定基数或类型。数字8357是Java中的int,其中8357L是一个long(因为末尾有一个'L')。如果变量可以从数字开始,那么可能会出现无法判断它是变量名还是文字的情况。

我会假设你列出的其他人有类似的原因,其中一些可能是历史的(即C无法理解 X ,而Java的设计看起来像C所以他们遵守规则。)

在实践中,它们几乎不是问题。你很难找到这种令人烦恼的情况。你最常遇到的是以数字开头的变量,但你总是可以拼出它们(即oneThing,twoThing,threeThing等)。

答案 4 :(得分:1)

语言可能允许其中的一些,但这种简化的假设使编译器编写者和程序员更容易阅读程序。

解析器(通常)编写为首先将源文本分解为“标记”。以数字开头的标识符看起来像一个数字。除了5e3,在某些语言中是有效数字(5000.0)。

同时:和。被标记为运算符。在某些情况下,以其中一个开头的标识符会导致模糊代码。等等。

答案 5 :(得分:0)

每种语言都需要定义什么是标识符的有效字符,什么不是。部分考虑是易于解析,部分是为了避免歧义(换句话说,即使是完美的解析算法也不能一直确定),部分将是语言设计的偏好(在Java的情况下与C,C ++相似),有些只是随意的。

关键在于它必须是某种东西,所以这就是它。

答案 6 :(得分:0)

例如,我们是否希望拥有具有这些名称的对象?

2ndInning
3rdBase
4thDim
7thDay

但想象一下有人可能会尝试使用名称为666的变量:

int 666 = 777;
float 666F = 777F;
char 0xFF = 0xFF;
int a = 666; // is it 666 the variable or the literal value?
float b = 666F // is it 666F the variable or the literal value?

也许,我们可能会想到的一种方式是,以数字开头的变量必须以字母结尾 - 只要 它不以0x开头,以一个用作十六进制数字的字母结束,或者 它不会以L或F等字符结尾, 等等。

但是这样的规则会让Yogi Berra讽刺的程序员真的很难 - 你怎么能同时思考和打击呢?您正在尝试尽可能快地编写计算机程序并且没有错误,然后您将不得不烦恼所有这些小部分规则。作为程序员,我宁愿对如何命名变量有一个简单的规则。

在我使用词法分析器和regexp解析数据日志和数据流以插入数据库的努力中,我没有发现有一个以数字开头的关键字或变量会使其难以解析 - 所以只要有一个短的a路径尽可能消除歧义。

因此,它不仅仅是为了使编译器更容易,而是为了程序员。