Java main()メソッドのメソッドシグネチャは次のとおりです。
public static void main(String[] args){
...
}
このメソッドが静的である理由はありますか?
Java main()メソッドのメソッドシグネチャは次のとおりです。
public static void main(String[] args){
...
}
このメソッドが静的である理由はありますか?
回答:
それ以外の場合はあいまいさがあるため、メソッドは静的です:どのコンストラクターを呼び出す必要がありますか?特にクラスが次のようになっている場合:
public class JavaClass{
protected JavaClass(int x){}
public void main(String[] args){
}
}
JVMは呼び出す必要がありますnew JavaClass(int)
か?それは何のために渡すべきx
ですか?
そうでない場合、JVM JavaClass
はコンストラクタメソッドを実行せずにインスタンス化する必要がありますか?クラス全体が特殊なケースになるので、そうすべきではないと思います。初期化されていないインスタンスがあり、呼び出される可能性のあるすべてのメソッドでそれを確認する必要がある場合があります。
エントリポイントが呼び出される前に、JVMがクラスをインスタンス化しなければならないという意味では、エッジケースとあいまいさが多すぎます。それmain
が静的である理由です。
なぜmain
いつもマークされてpublic
いるのか分かりません。
public static void main
エントリーポイントのマーカーとして機能するのが好きです–公開パラメーターなしコンストラクターは「これはおそらくエントリーポイントです!」と叫びません。同じやり方で。
main
を呼び出すかについても、同じ「問題」があります。奇妙なことに(あなたにとって)、JVMはこれを適切に管理します。
これは単なる慣習です。実際、名前main()と渡された引数でさえ、純粋に慣例です。
java.exe(またはWindowsではjavaw.exe)を実行すると、実際に起こっているのは、いくつかのJava Native Interface(JNI)呼び出しです。これらの呼び出しは、実際にはJVMであるDLLをロードします(そうです-java.exeはJVMではありません)。JNIは、仮想マシンの世界とC、C ++などの世界をつなぐ必要があるときに使用するツールです。逆も当てはまります。実際には、(少なくとも私の知る限り) JNIを使用せずに実行されているJVM。
基本的に、java.exeはコマンドラインを解析し、JVMに新しい文字列配列を作成してそれらの引数を保持し、main()を含むと指定したクラス名を解析し、JNI呼び出しを使用して、 main()メソッド自体、次にmain()メソッドを呼び出し、新しく作成された文字列配列をパラメーターとして渡します。これは、Javaからのリフレクションを使用する場合と非常によく似ています。代わりに、紛らわしい名前のネイティブ関数呼び出しを使用するだけです。
独自のバージョンのjava.exe(ソースはJDKとともに配布されます)を作成し、まったく異なるものを実行することは完全に合法です。実際、それが私たちのすべてのJavaベースのアプリで行っていることです。
Javaアプリにはそれぞれ独自のランチャーがあります。主にこれを行うので、独自のアイコンとプロセス名を取得しますが、通常のmain()呼び出し以外に何かを実行したい場合(たとえば、あるケースでは、 COMの相互運用性。実際には、COMハンドルを文字列配列ではなくmain()に渡します。
つまり、長くて短く、静的である理由は、便利なb / cです。'main'と呼ばれるのは、それが何かである必要があったためです。main()は、Cの昔(そして当時、関数の名前が重要でした)で行ったことです。java.exeでは、クラス(java com.mycompany.Foo.someSpecialMain)の代わりに、完全修飾されたメインメソッド名のみを指定できたかもしれませんが、IDEでの自動検出がより難しくなりますプロジェクト内の起動可能なクラス。
java.exe
)
static
ではないと思いますmain()
。ただし、それが「main()」であり、他のものではないという事実は実現可能です。
main
静的ではなく、言語の境界内に収まる可能性があります。デザイナーからの連絡がなければ、同意しないことに同意する必要があります。:)
、およびのmain()
メソッドは静的です。これらのオブジェクトは、オブジェクトをインスタンス化する必要なしに
ランタイムエンジンによって呼び出すことができるため、の本体のコードが残りを実行します。C++
C#
Java
main()
public static void main...
、アプリケーションのエントリポイントクラスにデフォルトのパブリックコンストラクターが必要であるという規則を採用できないのはなぜですか?
static void main
を呼び出すかをどのようにして知るのでしょうか?全く問題ありません。
static
ようなメソッド。main
new
これは、Java言語が設計され、Java仮想マシンが設計および記述される方法です。
第12章の実行-セクション12.1.4 Test.mainの呼び出しを確認してください。
最後に、Testクラスの初期化が完了すると(他の結果として生じるロード、リンク、および初期化が発生した可能性がある間に)、Testのメソッドmainが呼び出されます。
mainメソッドはpublic、static、およびvoidで宣言する必要があります。文字列の配列である単一の引数を受け入れる必要があります。このメソッドは、次のいずれかとして宣言できます
public static void main(String[] args)
または
public static void main(String... args)
第2章Javaプログラミング言語の概念-セクション2.17実行を確認してください。
Java仮想マシンは、指定されたクラスのメソッドmainを呼び出し、文字列の配列である単一の引数をそれに渡すことにより、実行を開始します。これにより、指定されたクラスがロードされ(§2.17.2)、使用される他の型にリンクされ(§2.17.3)、初期化されます(§2.17.4)。mainメソッドはpublic、static、およびvoidで宣言する必要があります。
ソースjarをダウンロードして抽出し、JVMの記述方法を確認し../launcher/java.c
ます。チェックアウトには、コマンドの背後にネイティブCコードが含まれていますjava [-options] class [args...]
。
/*
* Get the application's main class.
* ... ...
*/
if (jarfile != 0) {
mainClassName = GetMainClassName(env, jarfile);
... ...
mainClass = LoadClass(env, classname);
if(mainClass == NULL) { /* exception occured */
... ...
/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
"([Ljava/lang/String;)V");
... ...
{ /* Make sure the main method is public */
jint mods;
jmethodID mid;
jobject obj = (*env)->ToReflectedMethod(env, mainClass,
mainID, JNI_TRUE);
... ...
/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
ReportExceptionDescription(env);
goto leave;
}
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
... ...
main
が静的でなかった場合は、クラスインスタンスの状態がわかっている必要があり、どのコンストラクタを最初に使用するかなど、定義がはるかに複雑になります。
public static void main(String arguments[])
参照:Oak 0.2 Spec。
Runnable
。プロセス全体を同じ方法で(つまりRunnable.Run
、エントリポイントとして持つことで)表すことは、Javaでは間違いなく理にかなっています。もちろん、Runnable
それ自体は間違いなく設計上の欠陥であり、Javaには(まだ)匿名メソッドがないために発生します。しかし、すでにそこにあるので…
単純にstatic
、アプリケーションのエントリポイントとして必要ないふりをしましょう。
アプリケーションクラスは次のようになります。
class MyApplication {
public MyApplication(){
// Some init code here
}
public void main(String[] args){
// real application code here
}
}
コンストラクタコードとの違い main
オブジェクト指向ではコンストラクタはインスタンスが適切に初期化されていることを確認するだけなので、メソッドが必要です。初期化後、インスタンスは目的の「サービス」に使用できます。完全なアプリケーションコードをコンストラクターに入れると、それが台無しになります。
したがって、このアプローチでは3、アプリケーションに異なる契約されます。
main
1。OK、これは驚くべきことではありません。abstract
。それ以外の場合、JVMはそれをインスタンス化できませんでした。static
一方、アプローチは、必要と一つ契約を:
main
メソッドが必要です1。ここにも abstract
のコンストラクタも重要ん。
Javaはユーザーにとって単純な言語になるように設計されているので、アプリケーションのエントリポイントも次のように簡単な方法で設計されているのは当然です。 1つのコントラクトを 3つの独立したもろいコントラクト。
注意:この引数は、JVM内またはJRE内の単純さに関するものではありません。この議論は、ユーザーにとっての単純さについてです。
main
ある方法public
、static
および署名を有しますvoid main(String[])
。メソッドがインスタンスメソッドである場合、JREは少し多くの作業を必要としますが、作業の種類は同じであり、複雑度はそれほど高くありません(前の回答のコメントの説明を参照)。特に、インスタンスメソッドの解決に必要なメソッドが存在し、すぐに使用できるため、この違いがエントリポイントを静的にする決定の原因とは思われません。
static public main(String[])
メソッドは1つの署名であり、したがって1つの契約です。それ以外の場合は、3つの独立した契約に従う必要があります。
Runnable
。明らかに、Javaは開発者が常にその契約に従うことを期待していますが、アプリケーションのエントリポイントとしては多すぎるのはなぜですか?それは意味がありません。
Thread
と Runnable
ケース何もユーザーから隠されていない、彼は明らかに何が起こっているのか見ることができると彼は実装するために変更があるだけで、彼に合うそれらの契約を-彼は、システム、コントロールではありません。
mainメソッドが呼び出される前は、オブジェクトはインスタンス化されていません。staticキーワードを使用すると、最初にオブジェクトを作成せずにメソッドを呼び出すことができます。
これらのことをもっと簡単な方法で説明しましょう。
public static void main(String args[])
アプレットを除くすべてのJavaアプリケーションは、から実行を開始しmain()
ます。
キーワードpublic
は、メンバーをクラスの外部から呼び出せるようにするアクセス修飾子です。
static
これはmain()
、そのクラスの特定のインスタンスをインスタンス化することなく呼び出すことができるためです。
void
がmain()
値を返さないことを示します。
の意味はpublic static void main(String args[])
何ですか?
public
アクセス指定子であり、JVM(Java Virtual Machineなど)はだれでもアクセス/起動できます。static
main()
クラスのオブジェクトが作成される前に呼び出すことができます。main()
オブジェクトが作成される前にJVMによって呼び出されるため、これは必要です。静的なので、クラスを介して直接呼び出すことができます。
class demo {
private int length;
private static int breadth;
void output(){
length=5;
System.out.println(length);
}
static void staticOutput(){
breadth=10;
System.out.println(breadth);
}
public static void main(String args[]){
demo d1=new demo();
d1.output(); // Note here output() function is not static so here
// we need to create object
staticOutput(); // Note here staticOutput() function is static so here
// we needn't to create object Similar is the case with main
/* Although:
demo.staticOutput(); Works fine
d1.staticOutput(); Works fine */
}
}
同様に、オブジェクトを作成する必要がないように、ユーザー定義メソッドにstaticを使用することがあります。
void
main()
宣言されているメソッドが値を返さないことを示します。
String[] args
メソッド内の唯一のパラメーターを指定しますmain()
。
args
-クラス型のオブジェクトの配列を含むパラメータString
。
さまざまな種類のアプレット、ミッドレット、サーブレット、およびBeanが構築され、ライフサイクルメソッドが呼び出されます。mainを呼び出すだけで、メインクラスに対して行われる処理がすべて完了するため、複数回呼び出されるオブジェクトに状態を保持する必要はありません。mainを別のクラスにピン留めするのはごく普通のことです(ただし、すばらしいアイデアではありません)。これは、クラスを使用してメインオブジェクトを作成する際に邪魔になります。
これは単なる慣例ですが、おそらく他の方法より便利です。静的メインの場合、Javaプログラムを呼び出すために知っておく必要があるのはクラスの名前と場所だけです。静的でない場合は、そのクラスをインスタンス化する方法を知っているか、クラスに空のコンストラクターが必要であることも必要です。
java
次のコマンドでJava仮想マシン(JVM)を実行すると、
java ClassName argument1 argument2 ...
アプリケーションを実行するときは、上記のように、javaコマンドの引数としてそのクラス名を指定します
JVMは、指定したクラスのメインメソッドを呼び出そうとします
-この時点では、クラスのオブジェクトは作成されていません。
クラスのを主に作成するために、JVMを
main
静的として宣言します。allows
invoke
without
instance
コマンドに戻りましょう
ClassName
でcommand-line argument
実行するためにどのクラスにそれを伝えるJVMに。ClassNameに続いlist of Strings
て、JVMがアプリケーションに渡すコマンドライン引数として(スペースで区切られた)を指定することもできます。-このような引数は、アプリケーションを実行するためのオプション(ファイル名など)を指定するために使用される可能性があります。これがString[] args
、メインで呼び出されるパラメーターがある理由です。
最近、同様の質問がProgrammers.SEに投稿されました。
(特に)JavaとC#が、アプリケーションインスタンスを
Application
クラスのインスタンスで表すのではなく、静的メソッドをエントリポイントとして持つことにした理由について、プライマリまたはセカンダリソースからの明確な回答を探しています。適切なコンストラクタ?
Javaでは、その理由
public static void main(String[] args)
は
- ゴスリングが欲しかった
- C(Javaではない)の経験者が作成したコード
- 誰かによって実行されるように実行するように使用のPostScriptを上ニュース
C#の場合、推論は、一言で言えば推移的に似ています。言語設計者は、Javaから来たプログラマーにとって馴染みのあるプログラムエントリポイント構文を維持しました。C#アーキテクトのAnders Hejlsbergが言うように、... C#を使用したアプローチは、Javaプログラマーに代替手段を提供することです...
...
main()は静的です。アプリケーションのライフサイクルのその時点では、インスタンス化されているオブジェクトがないため、アプリケーションスタックは本質的に手続き型です。
白紙の状態です。オブジェクトが宣言されていなくても、アプリケーションはこの時点で実行されています(手続き型およびOOコーディングパターンがあることに注意してください)。開発者は、オブジェクトのインスタンスを作成し、コンパイルされたコードに応じて、アプリケーションをオブジェクト指向のソリューションに変換します。
オブジェクト指向は、何百万もの明らかな理由で優れています。ただし、ほとんどのVB開発者がコードで "goto"などのキーワードを定期的に使用していた時代は終わりました。"goto"はVBの手続き型コマンドで、それに対応するOOのメソッド呼び出しによって置き換えられています。
静的エントリポイント(メイン)を純粋な自由として見ることもできます。Javaがオブジェクトをインスタンス化して実行時にそのインスタンスのみを提示するほど十分に異なっていた場合、手続き型アプリを作成する選択肢はありません。Javaの場合とは思えないほど想像できないほど、手続き型のアプローチを必要とする多くのシナリオが考えられます。
これはおそらく非常にあいまいな応答です。「クラス」は相互に関連するコードのコレクションにすぎないことを覚えておいてください。「インスタンス」は、そのクラスの孤立した、生きている、呼吸する自律的な世代です。
main
到達する前に、多くのオブジェクトがインスタンス化されます。また、mainを含むクラスに静的コンストラクターを含めると、main
同じように前に実行されます。
プロトタイプpublic static void main(String[])
は、JLSで定義された規則です。
mainメソッドはpublic、static、およびvoidで宣言する必要があります。宣言された型が文字列の配列である仮パラメーター(8.4.1)を指定する必要があります。
Java仮想マシンは、ブートストラップクラスローダー(§5.3.1)を使用して、実装依存の方法で指定された初期クラスを作成することによって起動します。次に、Java仮想マシンは初期クラスをリンクし、初期化して、パブリッククラスメソッドvoid main(String [])。このメソッドの呼び出しにより、以降のすべての実行が駆動されます。mainメソッドを構成するJava仮想マシン命令を実行すると、追加のクラスとインターフェースのリンク(および結果として作成)が発生し、追加のメソッドが呼び出される場合があります。
おかしなことに、JVM仕様では、メインメソッドが静的でなければならないことについては触れられていません。しかし、この仕様では、Java仮想マシンは2つのステップを以前に実行することも述べています。
クラスまたはインターフェースの初期化は、そのクラスまたはインターフェースの初期化メソッドの実行で構成されます。
では2.9。特別な方法:
クラスまたはインタフェースの初期化方法が定義されます。
クラスまたはインターフェースには、最大で1つのクラスまたはインターフェース初期化メソッドがあり、そのメソッドを呼び出すことによって初期化されます(§5.5)。クラスまたはインターフェースの初期化メソッドは特別な名前
<clinit>
を持ち、引数を取らず、無効です。
そしてクラスまたはインタフェースの初期化方法は、異なるインスタンスの初期化方法、次のように定義されます。
Java仮想マシンのレベルでは、Javaプログラミング言語(JLS§8.8)で記述されたすべてのコンストラクターは、特別な名前を持つインスタンス初期化メソッドとして表示されます
<init>
。
したがって、JVMはクラスまたはインターフェースの初期化メソッドを初期化し、実際にはコンストラクターであるインスタンス初期化メソッドを初期化しません。したがって、メインメソッドを呼び出す前にインスタンスが作成されないという事実によって暗示されるため、JVM仕様ではメインメソッドが静的である必要があることを言及する必要はありません。
public
キーワードは、プログラマがクラスメンバーの可視性を制御することを可能にするアクセス修飾子です。クラスメンバーの前にpublic
場合、そのメンバーは、それが宣言されているクラス外のコードからアクセスできます。
public
is の反対はprivate
、メンバーがクラスの外部で定義されたコードによって使用されるのを防ぎます。
この場合は、プログラムの起動時にクラス外のコードから呼び出す必要があるため、main()
として宣言public
する必要があります。
キーワードをstatic
使用
main()
すると、クラスの特定のインスタンスをインスタンス化せずに呼び出すことができます。main()
オブジェクトが作成される前にJavaインタープリターによって呼び出されるため、これは必要です。
このキーワードvoid
は、main()
値を返さないようコンパイラーに指示するだけです。
アプリケーションへの真のエントリポイントは、静的メソッドです。Java言語がインスタンスメソッドを「エントリポイント」としてサポートしている場合、ランタイムは、オブジェクトのインスタンスを作成した静的メソッドとして内部的に実装し、その後インスタンスメソッドを呼び出す必要があります。
それが邪魔にならないように、次の3つのオプションの特定の1つを選択する根拠を調べます。
static void main()
今日見ます。void main()
新しく作成されたオブジェクトで呼び出されるインスタンスメソッド。Program
場合、実行は事実上で構成されますnew Program()
)。static void main()
main()
。void main()
new ClassName()
。main()
。new ClassName()
これは逆の順序で行います。
Javaの設計目標の1つは、優れたオブジェクト指向プログラミングの実践を強調(可能な場合は必須)することでした。このコンテキストでは、オブジェクトのコンストラクターがオブジェクトを初期化しますが、オブジェクトの動作に責任を持つべきではありません。したがって、エントリポイントを指定した仕様は、new ClassName()
すべてのアプリケーションの「理想的な」コンストラクタの設計に例外を強制することにより、新しいJava開発者の状況を混乱させます。
main()
インスタンスメソッドを作成することで、上記の問題は確実に解決されます。ただし、エントリクラスのコンストラクタのシグネチャとmain()
メソッドのシグネチャをリストするように指定する必要があるため、複雑になります。
要約すると、a static void main()
を指定すると、動作をメソッドに配置するという原則に従いながら、最小の複雑さで仕様が作成されます。。main()
それ自体がクラスのインスタンスを作成してインスタンスメソッドを呼び出すメソッドを実装するのがいかに簡単かを考えると、インスタンスメソッドmain()
として指定することには実際的な利点はありません。
main
。main
初心者には複雑すぎるというあなたの理論的根拠は信じられないようです。実際、static main
は初心者にとって非常に混乱します。コンストラクターはもっと混乱するでしょう。「コンストラクタはオブジェクトの動作に責任を負うべきではない」とあなたは言う。これは面白そうに聞こえますが、私が同意するかどうかはわかりません。なぜそれはありませんか?これを防ぐものは何ですか?
オブジェクトがインスタンス化される前にJVMがmainメソッドを呼び出すかどうかはわかりません...しかし、main()メソッドが静的である理由ははるかに強力です... JVMがクラスのmainメソッドを呼び出すとき(たとえば、人)。「Person.main()」で呼び出します。ご覧のとおり、JVMはクラス名でそれを呼び出します。そのため、JVMからアクセスできるように、main()メソッドは静的かつパブリックである必要があります。
お役に立てば幸いです。もしそうなら、コメントで知らせてください。
ここに見られるように、これは単なる規則です。
メソッドはpublicおよびstaticとして宣言する必要があり、値を返さないようにする必要があります。また、String配列をパラメーターとして受け入れる必要があります。デフォルトでは、最初の非オプション引数は、呼び出されるクラスの名前です。完全修飾クラス名を使用する必要があります。-jarオプションが指定されている場合、最初の非オプション引数は、アプリケーションのクラスおよびリソースファイルを含むJARアーカイブの名前であり、スタートアップクラスはMain-Classマニフェストヘッダーで示されます。
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description
public static voidキーワードは、Java仮想マシン(JVM)インタープリターがプログラムのメインメソッドを呼び出して、クラス(静的)のインスタンスを作成せずにプログラム(パブリック)を開始でき、プログラムがJava VMインタープリターにデータを返さないことを意味します(void)終了したとき。
Javaで静的として宣言されたメソッドはすべて、クラス自体に属します。繰り返しますが、特定のクラスの静的メソッドは、次のようなクラスを参照することによってのみアクセスできますClass_name.method_name();
そのため、静的メソッドにアクセスする前にクラスをインスタンス化する必要はありません。
したがって、main()メソッドは次のように宣言されます static
、そのクラスのオブジェクトを作成せずにアクセスできるようにています。
mainメソッドが存在するクラスの名前で(またはプログラムが実行を開始する場所から、main()
method()(Advanced Level)のないクラスに適用可能)プログラムを保存するため。したがって、上記の方法で:
Class_name.method_name();
mainメソッドにアクセスできます。
簡単に言うと、プログラムがコンパイルされると、次のような引数main()
を持つメソッドが検索されます。言及されたクラス(つまり、プログラムの名前)で、最初からそのクラスをインスタンス化するスコープがないため、main()メソッドは静的として宣言されています。String
main(String args[])
java.sun.comから(サイトに詳細情報があります):
mainメソッドは静的で、Java VMインタープリターが、最初にコントロールクラスのインスタンスを作成せずにクラスを開始する方法を提供します。コントロールクラスのインスタンスは、プログラムの起動後にmainメソッドで作成されます。
私の理解では、メインメソッドは、静的メソッドと同様に、関連付けられたクラスのインスタンスを作成せずに呼び出すことができ、プログラム内の他のどのメソッドよりも先に実行できるというだけでした。静的でない場合は、オブジェクトを呼び出す前にインスタンス化する必要があります。これは、メインのメソッドが通常、プログラムの最初にオブジェクトをインスタンス化するために使用するものであるため、「鶏と卵」の問題を引き起こします。
Runnable
Javaの類似オブジェクト(スレッド、経由)からこの設計が使用されています。なぜ(見かけ上の)例外がここにあるのですか?