main是一个有效的Java标识符吗?

Gar*_*Bak 285 java program-entry-point identifier language-lawyer

我的一个孩子正在高中学习Java,并在他的一个测试中得到了这个:

以下哪项是Java中的有效标识符?

一个. 123java
main
C. java1234
d. {abce
)whoot

他回答了b并弄错了.

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

我们看了一下标准的Java 规范,并强调了这一点.我们还编写了一个示例程序,其中包含一个名为变量的变量main,以及一个方法.他创建了一个书面反驳,包括Java文档参考,测试程序和老师忽略它,并说答案仍然是错误的.

main有效的标识符吗?

rge*_*man 251

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这会编译,并在执行时发出以下输出:

The character sequence "main" is an identifier, not a keyword or reserved word.
Run Code Online (Sandbox Code Playgroud)

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

JLS相关部分是3.8:

一个标识符是无限长序列的Java字母爪哇位,其中第一个必须是一个爪哇字母.

标识符:

    IdentifierChars但不是Keyword或BooleanLiteral或NullLiteral

IdentifierChars:

    JavaLetter {JavaLetterOrDigit}

JavaLetter:

    任何Unicode字符都是"Java字母"

JavaLetterOrDigit:

    任何Unicode字符,即"Java字母或数字"

字符序列main符合上述说明,不在第3.9节关键字列表中.

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

  • @Clockwork这个问题的措辞是这样的,只有一个选择是正确的.但是,两种选择**b**和**c**都满足了问题的条件,与隐含的选择不一致.这使得OP的孩子可以选择哪一个正确答案是唯一一个老师认为正确的答案. (25认同)
  • @TripeHound"是一个有效的标识符"是单数并且正好要求1个答案.将其与"有效标识符"进行比较 (6认同)
  • 您也可以将类设为“ main”;) (2认同)

Mik*_*kis 95

main 是一个有效的java标识符,老师错了.

相关文档在Java语言规范中,就在这里:

第3章"词汇结构",第3.8节."身份标识":

https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8

它说:

标识符是无限长度的Java字母和Java数字序列,第一个必须是Java字母...标识符不能与关键字(第3.9节)具有相同的拼写(Unicode字符序列),布尔文字( §3.10.3),或null文字(§3.10.7),或发生编译时错误.

这意味着您可以通过将其用作标识符并观察不发生编译时错误来证明它是有效的标识符.

  • 不,因为它是整个部分.如果老师认为这部分为"主要"做了某种例外,那么教师必须展示它所说的位置. (36认同)

MC *_*ror 76

正如其他答案所述

main是一个有效的Java标识符,以及java1234.

我想混淆的原因是该main(String[])方法经常被JVM 1用作入口点.但是,这并不意味着令牌main本身不能用作标识符2.

规范说明了,以下声明也是有效的:


1:如评论中所述,JVM规范本身并未强制要求任何特定方法作为入口点,但是广泛使用的java工具通常使用这样的方法作为入口点.
2:我通常会避免创建除主流之外的主要方法main(String[]).

  • 这更具有讽刺意味,因为即使在"入口点 - 上下文"中,主要的ALREADY也是一个有效的标识符.因此,即使是你可以坚持反对它的情况实际上证明了OP是正确的 (26认同)
  • *"我想混淆来自main(String [])方法用作JVM的入口点这一事实."*`main`不是JVM的入口点.这是`java`工具用来运行应用程序的入口点.其他工具(例如,servlet容器)使用其他入口点. (21认同)
  • 如果主类扩展,则`java`工具不需要`main(String [])`方法[javafx.application.Application](https://docs.oracle.com/javase/10/docs/api/javafx /application/Application.html). (4认同)
  • @Hobbamok _你似乎对基本的 Java 概念感到困惑,这可能解释了为什么你在学校教它而不是练习_是我想到的答案 (2认同)

Mic*_*elK 65

这在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

...并在执行时产生输出:

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
Run Code Online (Sandbox Code Playgroud)

  • @ jpmc26尝试一下,告诉我们它是怎么回事.:) (6认同)
  • 是否可以添加另一个具有不同参数的`static main`方法? (5认同)
  • @MCEmperor是的,这是我的答案的主要*参数.;) (4认同)
  • 你忘了添加`package main;`! (3认同)

dav*_*xxx 44

main当它被用作标识符来声明"主"方法时,怎么不能用作标识符?

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

public class Foo{
   public static void main(String[] args){
   }
}
Run Code Online (Sandbox Code Playgroud)

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


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

第一:对编译器有效并不一定意味着好.
例如java1234,建议的选项也是有效的标识符,但应该真正避免.

main具有非常特别和重要的意义:它被用作java命令行执行的类和jar的入口点方法.
使用main不填充java命令行使用的条件的方法名称只会误导,而将其用作变量名称或类名称可能有意义.
例如定义表示应用作为的入口点的类Main的类的应用是可以接受的,因此用它作为变量名太如:

public class Main {

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

}
Run Code Online (Sandbox Code Playgroud)

一般来说,在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$);
    }    
}
Run Code Online (Sandbox Code Playgroud)

但我们不想要:

  • 命名Object我们的类,因为它在java.lang(1)中定义.
  • main()如果未填充java命令行(2)要使用的条件,则命名方法.
  • 重载Object.toString()方法(3).
  • 用变量命名_,$或者任何与共享命名约定相反的令人惊讶/无意义的字符(4).

  • 需要注意的是,`main`可以是一个关键字,只能用作具有适当签名(或其他)的静态方法的名称.请注意,超类调用使用`super`,使其看起来像一个标识符:`super(foo);`和`super.foo`,但`super`是一个关键字(在添加泛型之前,这是使用它的唯一方法(我记得)). (7认同)
  • 我只是意味着它可以作为关键字完成.仅仅因为它看起来像一个标识符,并不意味着它必须是. (2认同)
  • 我认为`main`仍然是比`java1234`更好的标识符.将它用于"常规"方法会产生误导,但是如果它实际上是我方法中的主要内容,那么命名变量`main`就没有问题.`java1234`很糟糕,名字应该是描述性的...... (2认同)

181*_*107 44

我把所有可能的东西扔到了它,它似乎工作.我会说main是一个有效的标识符.

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 那段代码让我想起编程语言"ook"^^这段代码几乎每个单词都是"主"...... (3认同)
  • 我喜欢.试试'grep -o main main.java | wc -l' (2认同)
  • 我觉得我把它作为主线. (2认同)

小智 40

它是有效的标识符吗?是.

它是一个很好的标识符吗?如果您将其用于除JVM启动时启动的方法以外的任何其他内容,则不会.

是否列出了另一个有效标识 是.

测试说明是否说要选择最佳答案?

  • @Shadow这是一门编程课程.关于用正式数学语法指定的事物的问题的模糊性是不可容忍的.严格违反该标准(这是"**有效**"所暗示的),两个答案都同样正确.我可以想象更多的情况,其中`main`是一个可容忍的标识符,而不是`java1234`.例如,考虑使用供水数据(水管)的代码库. (19认同)
  • 同意 - 这样的多种选择是关于在有多个时选择"最佳"正确答案.然而,这并不能成为一个很好的多项选择问题,我认为与老师讨论这是正确的事情. (7认同)
  • 另一方面,java1234作为标识符向高天堂发恶臭. (5认同)
  • "选择最佳答案"并不意味着"弄清楚当老师不知道他们在说什么,并猜测他们正在考虑的错误答案." main不仅是一个*valid*标识符,它是一个非常重要的*标识符,因为每个Java应用程序都有一个main方法,而方法用标识符命名. (4认同)
  • 我觉得这个答案非常自以为是,我希望我能不止一次地投票.看来你正试图不惜一切代价而不考虑更广泛的情况.`main`是普通Java应用程序的窄域之外的任何一个完美的标识符.它可以是表示集合菜单的类中的字段的名称.或者HTML构建器中文档的"<main>"部分.另一方面,`java1234`和标识符一样糟糕. (2认同)

zer*_*298 31

main完全有效,因为它来自文档:

  1. 是"Java字母和Java数字的序列,其中第一个是Java字母"
  2. 不是关键字
  3. 不是布尔文字,即"true"或"false"
  4. 不是null字面值


kab*_*bar 29

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

这位老师在假设main不是有效的标识符或者只是简单地说错了问题时犯了一个小错误.他可能想说"一个好的标识符".
但是忽略了你儿子的论点,从而阻碍了他检查相关文献(Java规范)和进行实验(编写示例程序)的科学方法,这与教师应该做的完全相反.


小智 5

这两个mainjava123有效的标识符,主要不是保留关键字所以这是完全可以接受的使用,尽可能的去测试,你应该已经得到了一个点或半分最少.


sub*_*his 5

  1. 应该是单字.那是空间是不允许的.

    示例:mangoprice有效但芒果价格无效.

  2. 应以字母(字母)或下划线或$符号开头.

    示例:price,_price和$ price是有效的标识符.

  3. 不应该是Java的关键字,因为关键字对编译器具有特殊意义.

    示例:class或void等.

  4. 不应该以数字开头,但数字可以位于中间或末尾.

    示例:5mangoescost无效,mango5cost和mangocost5有效.

  5. Java中标识符的长度可以是65,535个字符,并且都很重要.标识符区分大小写.这就是芒果和芒果的区别对待.可以包含全部大写字母或小写字母或混合.

IDENTIFIER:它们是类名,方法名,变量名......

由于main不是保留字,并且根据上面用于定义标识符的说明,main是有效标识符,java1234也是由于上述说明而无效的选项.