Is main a valid Java identifier?
One of my kids is taking Java in high school and had this on one of his tests:
Which of the following is a valid identifier in Java?
a. 123java
b. main
c. java1234
d. {abce
e. )whoot
He answered b and got it wrong.
I looked at the question and argued that main is a valid identifier and that it should have been right.
We took a look at the Java spec for identifiers and it reinforced that point. We also wrote a sample program that had a variable called main, as well as a method. 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.
Is the main a valid identifier?
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.
The relevant section of the JLS is 3.8:
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter {JavaLetterOrDigit}
JavaLetter:
any Unicode character that is a "Java letter"
JavaLetterOrDigit:
any Unicode character that is a "Java letter-or-digit"
The character sequence main fits the above description and is not in the keyword list in Section 3.9.
(The character sequence java1234 is also an identifier, for the same reasons.)
main is a valid java identifier, and the teacher is wrong.
The relevant documentation is in the Java Language Specification, right here:
Chapter 3. "Lexical Structure", section 3.8. "Identifiers":
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.
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.
As the other answers state
main is a valid Java identifier, as well as java1234.
I guess the confusing comes from the fact that the main(String[]) method is often used as entry point by the JVM1. However, that doesn't mean that the token main itself cannot be used as identifier2.
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.
2: I would generally avoid creating a main method other than main(String[]).
This compiles fine on Java 1.8...
public class main {
public String main = "main";
public void main(String main) {
System.out.println("This object is an instance of the class " + this.getClass().getCanonicalName());
System.out.println("The value of the argument \"main\" for this call to the method \"main(String main)\" is " + main);
System.out.println("The value of the field \"main\" is " + this.main);
}
public static void main(String[] args) {
main main = new main();
main.main(main.main + main.main);
}
}
...and when executed produces the output:
This object is an instance of the class main
The value of the argument "main" for this call to the method "main(String main)" is mainmain
The value of the field "main" is main
How main could not be used as an identifier while it is used as identifier to declare the "main" method ?
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.
About the question, is main a good identifier ?
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.
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();
// ...
}
}
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.
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 in java.lang(1).
to name a method main() if doesn't fill the criteria to be used by the java command line (2).
to overload the Object.toString() method (3).
to name our variables with _, $ or any surprising/unmeaningful characters that go against the shared naming conventions (4).
Is it a valid identifier? Yes.
Is it a good identifier? Not if you're using it for anything other than the method that starts at JVM launch.
Is another valid identifier listed? Yes.
Did the test instructions say to choose the best answer?
I threw everything I could at it, and it appears to work. I'd say main is a valid identifier.
package main;
public class main {
static main main;
String Main;
main(String main) {
Main = main;
}
main(main main) {
System.out.println(main.Main);
}
main main(main main) {
return new main(main);
}
public static void main(main...Main) {
main:
for (main main : Main) {
main = (main instanceof Main) ? new main(main): main.main(main);
break main;
}
}
public static void main(String[] args) {
main = new main("main");
main.main(main, main);
main = main.new Main(main) {
main main(main main) {
return ((Main)main).main();
}
};
main.main(main);
main.main(main,main);
}
abstract class Main extends main {
Main(main main) {
super("main");
}
main main() {
main.Main = "Main";
return main;
}
}
}
main is perfectly valid because it, from the docs:
Is a "sequence of Java letters and Java digits, the first of which is a Java letter"
Is not a keyword
Is not a boolean literal i.e. "true" or "false"
Is not null literal
public class Main {
private static String main;
public static void main(String[] main) {
Main.main = main[0];
new Main().main(Main.main);
}
private void main(String main) {
System.out.println(main);
}
}
Both main and java123 are valid identifiers, main isn’t a reserved keyword so it’s perfectly acceptable to use, as far as the test goes you should’ve gotten a point or half a point at least.
You can use any word that not a Keyword, Boolean, Null or begins with Number as identifier, The word " main " is the most used identifier, but - in your case - you can use java1234.
Which of the following is a valid identifier in Java?
a. 123java
b. main
c. java1234
d. {abce
e. )whoot
He answered b and got it wrong.
I looked at the question and argued that main is a valid identifier and that it should have been right.
We took a look at the Java spec for identifiers and it reinforced that point. We also wrote a sample program that had a variable called main, as well as a method. 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.
Is the main a valid identifier?
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.
The relevant section of the JLS is 3.8:
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter {JavaLetterOrDigit}
JavaLetter:
any Unicode character that is a "Java letter"
JavaLetterOrDigit:
any Unicode character that is a "Java letter-or-digit"
The character sequence main fits the above description and is not in the keyword list in Section 3.9.
(The character sequence java1234 is also an identifier, for the same reasons.)
main is a valid java identifier, and the teacher is wrong.
The relevant documentation is in the Java Language Specification, right here:
Chapter 3. "Lexical Structure", section 3.8. "Identifiers":
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.
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.
As the other answers state
main is a valid Java identifier, as well as java1234.
I guess the confusing comes from the fact that the main(String[]) method is often used as entry point by the JVM1. However, that doesn't mean that the token main itself cannot be used as identifier2.
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.
2: I would generally avoid creating a main method other than main(String[]).
This compiles fine on Java 1.8...
public class main {
public String main = "main";
public void main(String main) {
System.out.println("This object is an instance of the class " + this.getClass().getCanonicalName());
System.out.println("The value of the argument \"main\" for this call to the method \"main(String main)\" is " + main);
System.out.println("The value of the field \"main\" is " + this.main);
}
public static void main(String[] args) {
main main = new main();
main.main(main.main + main.main);
}
}
...and when executed produces the output:
This object is an instance of the class main
The value of the argument "main" for this call to the method "main(String main)" is mainmain
The value of the field "main" is main
How main could not be used as an identifier while it is used as identifier to declare the "main" method ?
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.
About the question, is main a good identifier ?
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.
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();
// ...
}
}
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.
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 in java.lang(1).
to name a method main() if doesn't fill the criteria to be used by the java command line (2).
to overload the Object.toString() method (3).
to name our variables with _, $ or any surprising/unmeaningful characters that go against the shared naming conventions (4).
Is it a valid identifier? Yes.
Is it a good identifier? Not if you're using it for anything other than the method that starts at JVM launch.
Is another valid identifier listed? Yes.
Did the test instructions say to choose the best answer?
I threw everything I could at it, and it appears to work. I'd say main is a valid identifier.
package main;
public class main {
static main main;
String Main;
main(String main) {
Main = main;
}
main(main main) {
System.out.println(main.Main);
}
main main(main main) {
return new main(main);
}
public static void main(main...Main) {
main:
for (main main : Main) {
main = (main instanceof Main) ? new main(main): main.main(main);
break main;
}
}
public static void main(String[] args) {
main = new main("main");
main.main(main, main);
main = main.new Main(main) {
main main(main main) {
return ((Main)main).main();
}
};
main.main(main);
main.main(main,main);
}
abstract class Main extends main {
Main(main main) {
super("main");
}
main main() {
main.Main = "Main";
return main;
}
}
}
main is perfectly valid because it, from the docs:
Is a "sequence of Java letters and Java digits, the first of which is a Java letter"
Is not a keyword
Is not a boolean literal i.e. "true" or "false"
Is not null literal
public class Main {
private static String main;
public static void main(String[] main) {
Main.main = main[0];
new Main().main(Main.main);
}
private void main(String main) {
System.out.println(main);
}
}
Both main and java123 are valid identifiers, main isn’t a reserved keyword so it’s perfectly acceptable to use, as far as the test goes you should’ve gotten a point or half a point at least.
You can use any word that not a Keyword, Boolean, Null or begins with Number as identifier, The word " main " is the most used identifier, but - in your case - you can use java1234.
Comments
Post a Comment