我的一个孩子在高中学习Java,他的一次考试是这样的:

下列哪个在Java中是有效的标识符? 123 java。 b主要 c . java1234 d。{abce whoot e。)

他答了b,答错了。

我看了看这个问题,认为main是一个有效的标识符,它应该是正确的。

我们查看了标识符的Java规范,它加强了这一点。我们还编写了一个示例程序,其中包含一个名为main的变量和一个方法。他写了一份书面反驳,包括Java文档参考,测试程序和老师忽略了它,说答案仍然是错误的。

main是有效的标识符吗?


当前回答

main和java123都是有效的标识符,main不是保留关键字,所以使用它是完全可以接受的,就测试而言,你至少应该得到一分或半分。

其他回答

当main被用作声明“main”方法的标识符时,它如何不能用作标识符?

对于这样一个经典的习语:

public class Foo{
   public static void main(String[] args){
   }
}

main不是关键字,而且由于明显的复古兼容性原因,它可能永远不会成为Java中的关键字。


关于这个问题,main是一个好的标识符吗?

首先:对编译器有效并不意味着一定是好的。 例如,提议的java1234选项也是一个有效的标识符,但应该避免使用。

main has a very particularly and important meaning : it is used as the entry point method of classes and jars executed by the java command line. Using main for a method name that doesn't fill the criteria to be used by the java command line would be just misleading while using it as variable name or a class name could make sense. For example defining the class representing the entry point of an application as the Main class of the application is acceptable and so using it as variable name too such as :

public class Main {

  public static void main(String args[]){
     Main main = new Main();
     // ...
  }      

}

一般来说,在Java中,多个字符或“单词”被认为是编译器的有效标识符,但强烈不鼓励在客户端代码中使用(但生成的代码可能会这样做:例如嵌套类),因为它们不可读和/或真正具有误导性。

例如,这对于编译器来说是有效的:

public class Object { // 1
    public void foo() {
       ...
    }
}

public class BadChosenIdentifier {

    public static void main() { // 2
        new BadChosenIdentifier().toString(new Object());  
    }

    public void toString(Object java1234) { // 3, 4
        String _result$ = java1234 + " -> to avoid"; // 4
        System.out.println(_result$);
    }    
}

但我们不想:

将Object命名为我们的类,就像java.lang(1)中定义的那样。 如果不满足Java命令行(2)使用的条件,则将方法命名为main()。 重载Object.toString()方法(3)。 用_,$或任何违背共享命名约定的令人惊讶/毫无意义的字符来命名变量(4)。

正如其他答案所说

main是一个有效的Java标识符,java1234也是。

我想,这种混淆是由于main(String[])方法经常被JVM1用作入口点。但是,这并不意味着令牌main本身不能用作identifier2。

规范是这么说的,下面的声明也是有效的:

一个字段: 私人int主; 一个局部变量: 字符串main = ""; 一个方法: 无效主(){…} 类或接口(尽管不鼓励类或接口名称以小写开头): 类main{…} 一个包: 包主要;


1:正如评论中提到的,JVM规范本身并没有强制要求任何特定的方法作为入口点,但是广泛使用的java工具经常使用这样的方法作为入口点。 2:我通常会避免创建main方法而不是main(String[])。


附录:我不觉得这是咆哮的地方,但这里是我正确的拙见:标识符main和java1234一样有效,所以两者必须同等对待有效或错误。否则是不能容忍的。

public class J {
    public static void main(String[] args)
    {
        String main = "The character sequence \"main\" is an identifier, not a keyword or reserved word.";
        System.out.println(main);
    }
}

编译后执行,输出如下:

The character sequence "main" is an identifier, not a keyword or reserved word.

字符序列main是一个标识符,而不是关键字或保留字。

JLS的相关章节是3.8:

标识符是Java字母和Java数字的无限长度序列,其中第一个必须是Java字母。 标识符: IdentifierChars,但不是关键字或BooleanLiteral或NullLiteral IdentifierChars: JavaLetter {JavaLetterOrDigit} JavaLetter: 任何“Java字母”的Unicode字符 JavaLetterOrDigit: 任何“Java字母或数字”的Unicode字符

字符序列main符合上述描述,并且不在第3.9节的关键字列表中。

(出于同样的原因,字符序列java1234也是一个标识符。)

Should be single word. That is spaces are not allowed. Example: mangoprice is valid but mango price is not valid. Should start with a letter (alphabet) or underscore or $ symbol. Example: price, _price and $price are valid identifiers. Should not be a keyword of Java as keyword carries special meaning to the compiler. Example: class or void etc. Should not start with a digit but digit can be in the middle or at the end. Example: 5mangoescost is not valid and mango5cost and mangocost5 are valid. Length of an identifier in Java can be of 65,535 characters and all are significant. Identifiers are case-sensitive. That is both mango and Mango are treated differently. Can contain all uppercase letters or lowercase letters or a mixture.

它们是类名、方法名、变量名……

main不是保留字,根据上面定义标识符的解释,main是一个有效的标识符,java1234也是。由于上述解释,其余选项无效。

那位老师犯了一个小错误,要么认为main不是一个有效的标识符,要么只是问题的措辞错误。他可能是想说“一个很好的标识符”。 但是,忽视你儿子的论点,从而阻止他以科学的方法检查相关文献(Java规范)并进行实验(编写示例程序),这与教师应该做的事情完全相反。