本文翻译自:Is main a valid Java identifier?
One of my kids is taking Java in high school and had this on one of his tests: 我的一个孩子正在高中学习Java,并在他的一个测试中得到了这个:
Which of the following is a valid identifier in Java? 以下哪项是Java中的有效标识符?
a. 一个。
123java
b. 湾main
c. C。java1234
d. d。{abce
e. 即)whoot
He answered b and got it wrong. 他回答了b并弄错了。
I looked at the question and argued that main
is a valid identifier and that it should have been right. 我查看了这个问题,并认为main
是一个有效的标识符,它应该是正确的。
We took a look at the Java spec for identifiers and it reinforced that point. 我们看了一下标准的Java 规范 ,并强调了这一点。 We also wrote a sample program that had a variable called main
, as well as a method. 我们还编写了一个示例程序,它有一个名为main
的变量,以及一个方法。 He created a written rebuttal that included the Java documentation reference, the test program and the teacher ignored it and says the answer is still incorrect. 他创建了一个书面反驳,包括Java文档参考,测试程序和老师忽略它,并说答案仍然是错误的。
Is main
a valid identifier? main
是有效的标识符吗?
#1楼
参考:https://stackoom.com/question/3xiq2/main是一个有效的Java标识符吗
#2楼
main
is a valid java identifier, and the teacher is wrong. main
是一个有效的java标识符,老师错了。
The relevant documentation is in the Java Language Specification, right here: 相关文档在Java语言规范中,就在这里:
Chapter 3. "Lexical Structure", section 3.8. 第3章“词汇结构”,第3.8节。 "Identifiers": “身份标识”:
https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8 https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8
It says: 它说:
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter... An identifier cannot have the same spelling (Unicode character sequence) as a keyword (§3.9), boolean literal (§3.10.3), or the null literal (§3.10.7), or a compile-time error occurs. 标识符是无限长度的Java字母和Java数字序列,第一个必须是Java字母...标识符不能与关键字(第3.9节)具有相同的拼写(Unicode字符序列),布尔文字( §3.10.3),或null文字(§3.10.7),或发生编译时错误。
Which means that you can prove that it is a valid identifier by using it as an identifier and observing that no compile-time error occurs. 这意味着您可以通过将其用作标识符并观察不发生编译时错误来证明它是有效的标识符。
#3楼
main
is perfectly valid because it, from the docs : main
完全有效,因为它来自docs :
- Is a "sequence of Java letters and Java digits, the first of which is a Java letter" 是“Java字母和Java数字的序列,其中第一个是Java字母”
- Is not a keyword 不是关键字
- Is not a boolean literal ie "true" or "false" 不是布尔文字,即“true”或“false”
- Is not null literal 不是null字面值
#4楼
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);
}
}
This compiles, and when executed, emits this output: 这会编译,并在执行时发出以下输出:
The character sequence "main" is an identifier, not a keyword or reserved word.
The character sequence main
is an identifier, not a keyword or reserved word. 字符序列main
是标识符,而不是关键字或保留字。
The relevant section of the JLS is 3.8 : JLS的相关部分是3.8 :
An identifier is an unlimited-length sequence of Java letters and Java digits , the first of which must be a Java letter . 标识符是无限长度的Java字母和Java数字序列,第一个必须是Java字母 。
Identifier: 标识符:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral IdentifierChars但不是Keyword或BooleanLiteral或NullLiteral
IdentifierChars: IdentifierChars:
JavaLetter {JavaLetterOrDigit} JavaLetter {JavaLetterOrDigit}
JavaLetter: JavaLetter:
any Unicode character that is a "Java letter" 任何Unicode字符都是“Java字母”
JavaLetterOrDigit: JavaLetterOrDigit:
any Unicode character that is a "Java letter-or-digit" 任何Unicode字符,即“Java字母或数字”
The character sequence main
fits the above description and is not in the keyword list in Section 3.9 . 字符序列main
符合上述描述,不在第3.9节的关键字列表中 。
(The character sequence java1234
is also an identifier, for the same reasons.) (出于同样的原因,字符序列java1234
也是一个标识符。)
#5楼
As the other answers state 正如其他答案所述
main
is a valid Java identifier , as well as java1234
. main
是一个有效的Java标识符 ,以及java1234
。
I guess the confusing comes from the fact that the main(String[])
method is often used as entry point by the JVM 1 . 我想混淆来自于main(String[])
方法经常被JVM 1用作入口点。 However, that doesn't mean that the token main
itself cannot be used as identifier 2 . 但是,这并不意味着令牌main
本身不能用作标识符2 。
The specs say so, and the following declarations are also valid: 规范说明了,以下声明也是有效的:
A field: 一个字段:
private int main;
A local variable: 一个局部变量:
String main = "";
A method: 一个方法:
private void main() { ... }
A class (although a class name starting with lowercase is discouraged): 一个类(虽然不鼓励以小写字母开头的类名):
public class main { ... }
A package: 一套:
package main;
1: As noted in the comments, the JVM specification itself does not mandate any particular method as entry point, but the widely used java
tool often uses such a method as entry point. 1:如评论中所述,JVM规范本身并未强制要求任何特定方法作为入口点,但广泛使用的java
工具通常使用这样的方法作为入口点。
2: I would generally avoid creating a main method other than main(String[])
. 2:我通常会避免创建main(String[])
以外的main方法。
#6楼
How main
could not be used as an identifier while it is used as identifier to declare the "main" method ? 当main
用作标识符来声明“main”方法时,main如何不能用作标识符?
For such a classic idiom : 对于这样一个经典的成语:
public class Foo{
public static void main(String[] args){
}
}
main
is not a keyword and it would probably never be a keyword in Java for obvious retro compatibility reasons. main
不是关键字,由于明显的复古兼容性原因,它可能永远不会是Java中的关键字。
About the question, is main
a good identifier ? 关于这个问题, main
是一个好的标识符?
First : valid for a compiler doesn't mean necessarily good. 第一:对编译器有效并不一定意味着好。
For example the java1234
option that is proposed is also a valid identifier but that should really be avoided. 例如,建议的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. main
具有非常特别和重要的意义:它被用作java
命令行执行的类和jar的入口点方法。
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. 使用main
作为不填充java
命令行使用的条件的方法名称只会误导,而将其用作变量名或类名可能有意义。
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 : 例如,将表示应用程序入口点的类定义为应用程序的Main
类是可以接受的,因此将其用作变量名称,例如:
public class Main {
public static void main(String args[]){
Main main = new Main();
// ...
}
}
In a general way, in Java, multiple characters or "words" are considered valid identifiers for the compiler but are strongly discouraged to be used in the client code (but generated code may do that : nested classes for example) as not readable and/or really misleading. 一般来说,在Java中,多个字符或“单词”被认为是编译器的有效标识符,但强烈建议不要在客户端代码中使用(但生成的代码可能会这样做:例如嵌套类),因为它们不可读和/或者真的很误导。
For example this could be valid for the compiler : 例如,这可能对编译器有效:
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$);
}
}
But we don't want : 但我们不想要:
- to name
Object
our class as this is defined injava.lang
(1). 将Object
命名为Object
因为它在java.lang
(1)中定义。 - to name a method
main()
if doesn't fill the criteria to be used by thejava
command line (2). 如果没有填充java
命令行(2)要使用的条件,则命名方法main()
)。 - to overload the
Object.toString()
method (3). 重载Object.toString()
方法(3)。 - to name our variables with
_
,$
or any surprising/unmeaningful characters that go against the shared naming conventions (4). 使用_
,$
或任何与共享命名约定相反的令人惊讶/无意义的字符来命名我们的变量(4)。