web-dev-qa-db-ja.com

Mainは有効なJava識別子ですか?

私の子供の一人は高校でJavaを取っていて、彼のテストの1つでこれを受けました:

次のうちどれがJavaで有効な識別子ですか?

a。 123Java
b。 main
c。 Java1234
d。 {abce
e。 )whoot

彼は b と答えて間違っていた。

私は質問を見て、mainisは有効な識別子であり、それは正しいはずだったと主張しました。

私たちは識別子についてJava spec を見ました、そしてそれはその点を補強しました。メソッドと同様にmainという変数を持つサンプルプログラムも書きました。彼は、Javaドキュメンテーション参照、テストプログラム、そして教師がそれを無視したことを含む書面による反論を作成し、答えはまだ間違っていると言います。

mainは有効な識別子ですか?

282
Gary Bak
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、ただしKeywordまたはBooleanLiteralまたはNullLiteralは不可

IdentifierChars:

JavaLetter {JavaLetterOrDigit}

JavaLetter:

「Javaの文字」である任意のUnicode文字

JavaLetterOrDigit:

「Javaの文字または数字」である任意のUnicode文字

文字シーケンスmainは上記の説明に適合し、セクション3.9の キーワードリストにはありません

(同じ理由から、文字シーケンスJava1234も識別子です。)

252
rgettman

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.10.3)、またはnullリテラル(3.10.7)、またはコンパイル時エラーが発生した。

つまり、識別子として使用し、コンパイル時エラーが発生しないことを確認することで、それが有効な識別子であることを証明できます。

94
Mike Nakis

他の回答のとおり

mainは有効なJava識別子 、およびJava1234です。

私は混乱がmain(String[])メソッドが頻繁にJVMによってエントリポイントとして使用されているという事実から来ていると思います1。しかし、それはトークンmain自体が識別子として使用できないという意味ではありません。2

仕様はそう言っており、次の宣言も有効です。

  • フィールド

    private int main;
    
  • ローカル変数

    String main = "";
    
  • 方法:

    private void main() { ... }
    
  • クラス(小文字で始まるクラス名は推奨されませんが):

    public class main { ... }
    
  • パッケージ:

    package main;
    

1:コメントで述べたように、JVM仕様自体はエントリポイントとして特定のメソッドを要求しませんが、広く使用されているJavaツールはエントリポイントとしてそのようなメソッドをしばしば使用します。
2:私は一般的にmain(String[])以外のmainメソッドを作らないようにします。

75
MC Emperor

これは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);
    }
}

...そして実行されると出力を生成します。

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
64
MichaelK

私はそれに可能なすべてを投げました、そしてそれはうまくいくように見えます。 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;
        }
    }
}
44
18107

"main"メソッドを宣言するための識別子として使用されているのに、どのようにmainを識別子として使用することができませんでしたか?

そのような古典的な慣用句の場合:

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

mainはキーワードではありません。明らかな旧来の互換性の理由から、Javaのキーワードになることはおそらくないでしょう。


質問については、mainは良い識別子ですか?

まず、コンパイラーに有効であることが必ずしも良いことを意味するわけではありません。
例えば、提案されているJava1234オプションも有効な識別子ですが、実際には避けるべきです。

mainは、非常に特に重要な意味を持ちます。これは、Javaコマンドラインによって実行されるクラスおよびjarのエントリポイントメソッドとして使用されます。
mainコマンドラインで使用される基準を満たさないメソッド名にJavaを使用することは、それを変数名またはクラス名として使用するときに誤解を招くことになります。
たとえば、アプリケーションのエントリポイントを表すクラスをアプリケーションのMainクラスとして定義することは許容されます。そのため、次のように変数名としても使用します。

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)に反する驚くべき/意味のない文字で名前を付ける。
44
davidxxx

それは有効な識別子ですか?はい。

それは良い識別子ですか? JVMの起動時に開始される方法以外に使用しているのではありません。

別の有効な識別子がリストされていますか?はい。

テストの指示は最良の答えを選ぶように言っていましたか?

40
user1423956

mainは完全に有効なので、 ドキュメントから

  1. 「Javaの文字とJavaの数字の並び、最初のものはJavaの文字」です。
  2. キーワードではない
  3. ブール値リテラルではない つまり "true"または "false"
  4. nullリテラルではない
31
zero298
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);
    }
}
29
kabra.dabar

その教師は、 main が有効な識別子ではないと仮定するか、単に質問を間違って言い回しているかのどちらかで、小さな誤りをしました。彼はおそらく「良い識別子」と言うつもりだった。
しかし、息子の主張を無視して、関連する文献をチェックし(Java仕様)、実験を実行する(サンプルプログラムを書く)という科学的アプローチを妨げるのは、教師が想定することの正反対です。やる。

7
user82593
  1. 一言でなければなりません。それはスペースが許可されていないということです。

    例:mangopriceは有効ですが、mangoの価格は無効です。

  2. 文字(アルファベット)、アンダースコア、または$記号で始める必要があります。

    例:price、_price、$ priceは有効な識別子です。

  3. Keywordはコンパイラーにとって特別な意味を持つので、Javaのキーワードにしないでください。

    例:classまたはvoidなど

  4. 数字で始めるべきではありませんが、数字は中央または最後に置くことができます。

    例:5mangoescostは無効で、mango5costとmangocost5は有効です。

  5. Javaの識別子の長さは65,535文字ですが、すべて重要です。識別子は大文字と小文字を区別します。それはマンゴーとマンゴーの両方が異なって扱われるということです。すべての大文字、小文字、または混合を含めることができます。

IDENTIFIER:それらはクラス名、メソッド名、変数名です...

Mainは予約語ではなく、上記の説明に従って識別子mainは有効な識別子およびJava1234を定義するためのものです。

5
subhashis

mainJava123は両方とも valid 識別子であり、メインは予約キーワードではないので、テストが完了する限り使用することは完全に許容できます。

5
shavar