メインは有効なJava識別子ですか?


288

私の子供たちの1人は高校でJavaを取り入れており、彼のテストの1つでこれを体験しました。

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

a。 123java
b。 main
c。 java1234
d。 {abce
e。 )whoot

彼はbと答え、それを間違えた。

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

識別子のJava 仕様を調べたところ、その点が強化されました。またmain、メソッドと同様に、という変数を持つサンプルプログラムも作成しました。彼は、Javaドキュメンテーションリファレンス、テストプログラム、および教師を含む反論を書面で作成し、それを無視して、答えはまだ正しくないと述べています。

あるmain有効な識別子?


12
先生がとても不安で、何か新しいことを学び、間違いを認めることを恐れているのを見ると、いつも悲しくなります。
Ryan Lundy

そうだと思います。しかし、あなたは本当にそれを変数/メソッド名として使用すべきではありません(それでも明らかなケースですが)、教師が考えてポイントホームをドリルしようとしている場合-特にこの場合-メソッド名なら、私は彼/を見ることができます彼女のポイント。
バラル

3
あなたの息子の先生が彼の仕事を正しくやっているかどうか、この質問は本当に尋ねますか?2つの有効なJava識別子が表示されます。したがって、答えは「b」「c」です。だから先生は正しいです。または、何か不足していますか?これはどのようにSOの質問になりますか?コミュニティに参加していない人物について判断する...
jschnasse

1
これは、Javaについてではなく、教師についての質問です。
ACV

1
「あなた自身のトリック質問によってだまされた」ケースのもう一つ。教師は、このような試験問題を書く前に、少なくとも言語仕様を一目見る必要があります。
jrh

回答:


253
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同じ理由で、文字シーケンスも識別子です。)


25
@Clockwork質問は、1つの選択肢のみが正しかったように語られました。ただし、選択肢bcはどちらも、暗黙の選択肢とは異なり、質問の条件を満たしています。これにより、OPの子供は、教師が正しいと考えた唯一の正解を正解から選択できました。
rgettman 2018

@rgettman私は「次のうちどれを...」と読みましたが、bとc」は有効な応答になります。
TripeHound 2018

6
@TripeHoundは「有効な識別子です」は単数であり、正確に1つの回答を要求します。「有効な識別子である」と比較
Gimme the 411

2
あなたもクラスmainを作ることができたでしょう;)
Peter Lawrey '17

97

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)、またはコンパイル時エラーが発生します。

つまり、次のいずれかの方法で有効な識別子であることを証明できます。

  • Javaキーワードのリストでそれを探す(ヒント:そこにはありません!)または単に
  • これを識別子として使用し、コンパイル時エラーが発生しないことを確認します。

1
引用して、より明確に綴っていただけますか?
zero298 '10 / 10/18

36
いいえ、それはセクション全体なのでです。このセクションが「メイン」になんらかの例外を設けると教師が考える場合、それがどこにあるかを示さなければならないのは教師です。
Mike Nakis、2018

76

他の答えが述べるように

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[])ます。


22
「混乱を招くのは、main(String [])メソッドがJVMのエントリポイントとして使用されているためだと思います。」 mainは、JVMのエントリポイントではありません。これは、javaツールがアプリケーションを実行するために使用するエントリポイントです。他のツール(たとえば、サーブレットコンテナー)は他のエントリポイントを使用します。
TJクラウダー2018

27
これはさらに皮肉なことです。 "entry-point-context"でもメインはすでに有効な識別子であるためです。ですから、あなたがそれに対抗することができたとしても、実際にはOPが正しいことを証明しています
Hobbamok

@TJCrowderありがとう、私はそれを答えに含めました。
MC皇帝

1
@Hobbamok あなたは基本的なJavaの概念について混乱しているように見えます。それがおそらく学校でそれを教え、実践しない理由が頭に浮かぶ返事です
rath

4
javaこのツールは必要ありませんmain(String[])メインクラスが拡張する場合の方法をjavafx.application.Applicationを
VGR 2018

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);
    }
}

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

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

5
static mainパラメータの異なる別のメソッドを追加することはできますか?
jpmc26 2018

6
@ jpmc26試してみて、どうだったか教えてください。:)
MichaelK

1
まあそれはたくさんの本管です
MC Emperor

4
@MCEmperorはい、それが私の答えに対する私の主な議論です。;)
MichaelK 2018

3
追加するのを忘れましたpackage main;
ソロモンウッコ

45

私はそれにできる限りのことを投げました、そしてそれはうまくいくようです。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;
        }
    }
}

2
私はそれが好きです。'grep -o main main.java | wc -l '
Gary Bak

3
このコードは、プログラミング言語の "ook"を思い出させてくれます^^このコードのほとんどすべての単語は "main"です...
Florian Bach

public static void main(main...Main)スペースが足りない)うまくいきませんか?
GeroldBroserが2018

3
私はそれをメインライン化したような気がします。
ロスプレッサー2018

1
@GeroldBroserこれはよりクリーンですが、厳密には必要ありません。トークン間の空白は多くの場合オプションであり、2つの後続のトークンの連結が有効でない場合にのみ必要です。
MC皇帝

44

どうやって 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)で定義されているクラスの名前です。
  • コマンドラインでmain()使用される基準を満たさない場合にメソッドに名前を付けるにはjava(2)。
  • Object.toString()メソッド(3)をオーバーロードします。
  • 変数に名前を付けるには_$または、共有の命名規則に反する意外で意味のない文字を使用します(4)。

7
ちょうど注意してください、main適切な署名(または何でも)を持つ静的メソッドの名前としてのみ使用可能なキーワードである可能性があります。スーパークラスは、使用を呼び出すことに注意してくださいsuper、それは識別子のように見えるように:super(foo);super.fooが、superキーワードIS(およびジェネリック医薬品が追加される前に、これは)私が覚えていること(それを使用する唯一の方法でした)。
jaxad0127 2018

@ jaxad0127興味深い点ですが、完全には同意しません。実際にはそうではなく、将来的には互換性の理由からおそらくそうならないでしょう。main新しいバージョンのJavaでキーワードとして定義した場合、mainをメソッド名(またはメンバー名)として使用するコードはコンパイルできなくなります。使い方superジェネリック医薬品は、現時点では存在しなかったとして、ジェネリック医薬品では、既存のコード内の任意の副作用を持っていません。
davidxxx 2018

2
私はそれがキーワードとして行われたことを意味しました。識別子のように見えるからといって、必ずしもそうである必要はありません。
jaxad0127 2018

2
私はそれmainがまだより良い識別子であると主張しjava1234ます。「通常の」メソッドにそれを使用すると誤解を招くかもしれませんが、変数がmain実際に私のメソッドの主要なものである場合、変数に名前を付けることは問題ありません。java1234ひどいです、名前は
わかりやすいものにする

1
「質問について、主要な識別子は良いですか?」場合によります。私mainが見ている関数が水道のメインデータで何かをしたなら、私はおそらく名前が付けられた変数に目を向けないでしょう。私が製品コード見た場合は、スローしjava1234ます(そして、接頭辞が付いた他の変数が1233ないことを祈りますjava)。
jpmc26 2018

40

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

それは良い識別子ですか?JVMの起動時に開始するメソッド以外にそれを使用している場合は例外です。

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

テストの指示では、最良の答えを選択するように言われましたか?


7
同意-このような複数の選択肢は、複数ある場合に「最良の」正解を選択することです。しかし、それではこれが多肢選択問題として適切なものになるわけではなく、私は教師にそれについて話すことが正しいことだと思います。
シャドウ

19
@Shadowこれはプログラミングコースです。形式的な数学的文法で指定された何かについての質問のあいまいさは耐えられない。その標準(厳密には " valid "が暗示するもの)に対して厳密に言えば、どちらの答えも等しく正しいです。main許容できる識別子であるケースは、私が想定するケースよりもはるかに多くのケースを想像できjava1234ます。たとえば、給水データ(給水本管)を扱うコードベースを考えてみます。
jpmc26 2018

5
一方、java1234は識別子として高天に悪臭を放ちます。
ジョシュア

4
「ベストアンサーを選択する」とは、「先生が自分の話していることを知らず、考えている悪いアンサーを推測できない場合に判断する」という意味ではありません。mainは有効な識別子であるだけでなく、すべてのJavaアプリケーションにはmainメソッドがあり、メソッドには識別子を使用して名前が付けられるため、非常に重要な識別子です。
fluffysheap 2018

2
この回答は非常に意見が分かれているので、何度も反対票を投じたいと思います。あなたは何とかして一面をとろうとしていて、全体像を考慮していないようです。main単純なJavaアプリケーションの狭いドメインの外側のどこでも、完全に細かい識別子です。これは、セットメニューを表すクラスのフィールドの名前にすることができます。または、<main>HTMLビルダーのドキュメントのセクション。java1234一方、は識別子が取得するのと同じくらい恐ろしいものです。
toniedzwiedz


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);
    }
}

7

その教師は、mainが有効な識別子ではないと仮定するか、単に質問を間違って表現するかのいずれかで、小さな間違いをしました。彼はおそらく「良い識別子」を言うつもりでした。
しかし、息子の主張を無視して、関連する文献(Java仕様)を確認し、実験(サンプルプログラムを作成)を実行するという彼の科学的アプローチを思いとどまらせることは、教師がすべきこととは正反対です。


1
他の回答で述べたように、mainは「良い」識別子である場合よりもはるかに頻繁に使用されjava1234ます。ですから、先生は間違っています。;)
jpmc26 2018年

5

どちらmainjava123されている有効な、それははるかテストは、あなたがポイントまたは少なくとも半分のポイントを得ている必要があります行くようにと、使用することを完全に受け入れですので、メイン、識別子は予約語ではありません。


5
  1. 一言である必要があります。つまり、スペースは許可されていません。

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

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

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

  3. キーワードはコンパイラにとって特別な意味を持つため、Javaのキーワードであってはなりません。

    例:クラスまたはvoidなど

  4. 数字で始める必要はありませんが、数字は途中でも最後でもかまいません。

    例:5mangoescostは無効であり、mango5costおよびmangocost5は有効です。

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

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

mainは予約語ではないため、識別子を定義するための上記の説明によると、mainは有効な識別子であり、java1234も有効です。上記の説明のため、残りのオプションは無効です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.