Javamain()メソッドのメソッドシグネチャは次のとおりです。
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がクラスをインスタンス化しなければならないのは、Edgeのケースとあいまいさが多すぎるために意味がありません。 main
が静的なのはそのためです。
私はなぜmain
が常にpublic
とマークされるのかわかりません。
これは単なる慣例です。実際、main()という名前、および渡される引数でさえも、純粋に慣例です。
Java.exe(またはWindowsではjavaw.exe)を実行すると、実際に発生しているのは、2つのJNI(Java Native Interface)呼び出しです。これらの呼び出しは、実際にはJVMであるDLLをロードします(そうです - Java.exeはJVMではありません)。 JNIは、仮想マシンの世界とC、C++などの世界とを橋渡ししなければならないときに使用するツールです。その逆もまた真実です。実際には(少なくとも私の知る限りでは)不可能です。 JNIを使用せずにJVMが実行されている。
基本的に、Java.exeはコマンドラインを解析し、それらの引数を保持するためにJVMに新しいString配列を作成し、main()を含むものとして指定したクラス名を解析し、JNI呼び出しを使用して検索する単純なCアプリケーションです。次に、main()メソッド自体がmain()メソッドを呼び出し、新しく作成された文字列配列をパラメータとして渡します。これは、Javaからのリフレクションを使用したときの操作と非常によく似ています。代わりに、混乱を招くように名前が付けられたネイティブ関数呼び出しを使用します。
独自のバージョンのJava.exeを作成し(ソースはJDKと一緒に配布されます)、まったく別のことをすることは完全に合法です。実際、それはまさに私たちがすべてのJavaベースのアプリケーションで行っていることです。
私たちのJavaアプリケーションはそれぞれ独自のランチャーを持っています。これを主に行うのは独自のアイコンとプロセス名を取得するためですが、通常のmain()呼び出し以外に何かを実行したいという状況では便利です(たとえば、あるケースでは実行しています)。 COMの相互運用性、そして実際にはCOMハンドルを文字列配列の代わりにmain()に渡します。
だから、長短:それは静的である理由は便利ですB/Cです。それが 'main'と呼ばれる理由はそれが何かでなければならないということです、そしてmain()はCの昔に彼らがしたことです(そして当時、関数の名前 was important)。 Java.exeでは、クラス(Java com.mycompany.Foo.someSpecialMain)だけでなく、完全修飾メインメソッド名を指定することしかできなかったと思いますが、IDE上での自動検出が難しくなります。プロジェクト内の起動可能なクラス。
C++
、C#
およびJava
のmain()
メソッドは静的です。
これらはランタイムエンジン によって オブジェクトをインスタンス化することなく呼び出すことができるので、main()
の本体の中のコードが残りをします。
これが、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
を調べてください。これには、コマンドJava [-options] class [args...]
の背後にあるネイティブCコードが含まれています。
/*
* 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);
... ...
アプリケーションのエントリポイントとしてstatic
が必要ないというふりをしましょう。
アプリケーションクラスは次のようになります。
class MyApplication {
public MyApplication(){
// Some init code here
}
public void main(String[] args){
// real application code here
}
}
コンストラクタコードとmain
メソッドの区別が必要なのは、OOでコンストラクタはインスタンスがinitialized適切に。初期化後、インスタンスは目的の「サービス」に使用できます。完全なアプリケーションコードをコンストラクタに配置すると、それが台無しになります。
したがって、このアプローチでは、アプリケーションにthree異なる契約が強制されます。
main
メソッドが必要です1。わかりました、これは驚くことではありません。abstract
であってはなりません。そうしないと、JVMはそれをインスタンス化できませんでした。一方、static
アプローチでは、one契約のみが必要です。
main
メソッドが必要です1。ここでは、abstract
も複数のコンストラクタも重要ではありません。
Javaはユーザー向けのシンプルな言語になるように設計されているため、アプリケーションエントリポイントがone契約を使用する単純な方法であり、three独立した脆弱な契約を使用する複雑な方法ではありません。
注意:この引数は、JVM内またはJRE内の単純さについてnotです。この引数は、serの単純さについてです。
もしそうでなければ、複数のコンストラクタがあればどのコンストラクタを使うべきでしょうか?
Java言語仕様 で利用可能なJavaプログラムの初期化と実行に関するより多くの情報があります。
Mainメソッドが呼び出される前は、オブジェクトはインスタンス化されていません。 staticキーワードを持つということは、最初にオブジェクトを作成せずにメソッドを呼び出すことができるということです。
それ以外の場合は、実行するオブジェクトのインスタンスが必要になります。しかし、通常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 */
}
}
同様に、オブジェクトを作成する必要がないように、ユーザー定義メソッドにはいつか静的を使用します。
void
は、宣言されているmain()
メソッドが値を返さないことを示します。
String[] args
はmain()
メソッドの唯一のパラメータを指定します。
args
- クラス型String
のオブジェクトの配列を含むパラメータ.
これらのことをもっと簡単な方法で説明しましょう。
public static void main(String args[])
アプレットを除くすべてのJavaアプリケーションは、main()
から実行を開始します。
キーワードpublic
は、メンバーをクラスの外から呼び出せるようにするアクセス修飾子です。
そのクラスの特定のインスタンスをインスタンス化しなくてもmain()
を呼び出すことができるため、static
が使用されます。
void
は、main()
が値を返さないことを示します。
さまざまな種類のアプレット、ミッドレット、サーブレット、およびBeanが作成され、それらにライフサイクルメソッドが呼び出されます。 mainを呼び出すことは、メインクラスに対して行われることのすべてなので、複数回呼び出されるオブジェクトに状態を保持する必要はありません。 mainを別のクラスに固定するのはごく普通のことですが(これは素晴らしい考えではありませんが)、メインオブジェクトを作成するためにクラスを使用する際の邪魔になります。
これは単なる慣例ですが、おそらく代替手段よりも便利です。スタティックメインでは、Javaプログラムを呼び出すために知っておく必要があるのは、クラスの名前と場所だけです。静的でない場合は、そのクラスをインスタンス化する方法を知っておく必要があります。または、そのクラスに空のコンストラクターがあることを要求する必要があります。
Java
コマンドを使用してJava仮想マシン(JVM)を実行すると、
Java ClassName argument1 argument2 ...
アプリケーションを実行するときには、上記のように、そのクラス名をJavaコマンドへの引数として指定します。
jVMは指定されたクラスのmainメソッドを呼び出そうとします。
- この時点では、クラスのオブジェクトは作成されていません。
main
をstaticとしてallows
をJVMに宣言することでinvoke
mainwithout
にクラスのinstance
を作成する。
コマンドに戻りましょう
ClassName
はJVMへのcommand-line argument
で、実行するクラスを指示します。 ClassNameに続いて、JVMがアプリケーションに渡すコマンドライン引数としてlist of Strings
(スペース区切り)を指定することもできます。 - そのような引数は、アプリケーションを実行するためのオプション(例えば、ファイル名)を指定するために使用されるかもしれません - これがString[] args
と呼ばれるパラメータがメインにある理由です
Mainメソッドが静的ではない場合は、プログラムの外部からメインクラスのオブジェクトを作成する必要があります。どのようにそれをしたいですか?
最近、同様の質問がProgrammers.SEに投稿されました。
一次または二次情報源から最終的な答えを探して、なぜJavaとC#がエントリポイントとしてアプリケーションメソッドを
Application
クラスのインスタンスで表すのではなく、静的メソッドをエントリポイントとして持つことにしたのか適切なコンストラクタ?
受け入れられた答えの TL; DR 部分は、
Javaでは、
public static void main(String[] args)
の理由は、
- Gosling が欲しい
- cで経験した人が書いたコード(Javaではない)
- PostScript を NeWS で実行していた誰かによって実行される
C#の場合、推論は 推移的に似ています いわばいわば。言語設計者は、Javaから来るプログラマのために プログラムエントリポイント 構文をよく知っています。 C#アーキテクト Anders Hejlsbergが書いた 、... C#に対する私たちのアプローチは、単にJavaプログラマーに代わるものを提供することでした...
...
main()は静的です。アプリケーションのライフサイクルのその時点では、まだインスタンス化されているオブジェクトがないため、アプリケーションスタックは手続き型です。
きれいな状態です。オブジェクトは宣言されていなくても、アプリケーションはこの時点で実行されています(手続き型AND OOコーディングパターンがあります)。あなたは、開発者として、自分のオブジェクトのインスタンスを作成し、その中でコンパイルされたコードに応じて、アプリケーションをオブジェクト指向ソリューションに変えます。
オブジェクト指向は、何百万もの明白な理由から素晴らしいです。しかし、ほとんどのVB開発者がコード内で "goto"のようなキーワードを定期的に使用していた時代は終わりました。 "goto"はVB内の手続き型コマンドであり、対応するOOメソッド呼び出しに置き換えられています。
静的エントリポイント(main)を純粋な自由として見ることもできます。実行時にJavaがオブジェクトをインスタンス化してそのインスタンスのみを提示するのに十分なだけ異なる場合は、手続き型アプリケーションを作成することはできません。 Javaには思えないほど想像もできませんが、手続き型アプローチを必要とするシナリオは数多くあります。
これはおそらく非常にあいまいな回答です。覚えておいて、 "クラス"は相互に関連するコードの集まりにすぎません。 「インスタンス」とは、そのクラスの孤立した生きた呼吸自律的世代です。
プロトタイプpublic static void main(String[])
は、 _ jls _ で定義されている規則です。
メソッドmainは、public、static、およびvoidとして宣言する必要があります。宣言された型がStringの配列である仮パラメータ(8.4.1)を指定しなければならない。
JVMの仕様では 5.2。仮想マシンの起動 私たちは読むことができます:
Java仮想マシンは、ブートストラップクラスローダ(5.3.1)を使って、実装依存の方法で指定された初期クラスを作成することによって起動する。次に、Java仮想マシンは初期クラスをリンクして初期化し、 パブリッククラスメソッドvoid main(String []) を呼び出します。このメソッドを呼び出すと、それ以降のすべての実行が促進されます。メインメソッドを構成するJava仮想マシン命令を実行すると、追加のクラスやインタフェースのリンク(およびその結果の作成)、および追加のメソッドの呼び出しが発生する可能性があります。
おもしろいことに、JVM仕様では、メインメソッドが静的である必要があることは言及されていません。しかし、この仕様では、Java仮想マシンは2段階前に実行されるとも述べています。
クラスまたはインタフェースの初期化は、そのクラスまたはインタフェースの初期化メソッドを実行することからなります。
クラスまたはインタフェースの初期化メソッド が定義されています。
クラスまたはインタフェースは、最大で1つのクラスまたはインタフェース初期化メソッドを持ち、そのメソッドを呼び出すことによって初期化される(5.5)。クラスまたはインタフェースの初期化メソッドは特別な名前
<clinit>
を持ち、引数を取らず、voidです。
そして、 クラスまたはインターフェース初期化メソッド は、 インスタンス初期化メソッド とは異なり、次のように定義されます。
Java仮想マシンのレベルでは、Javaプログラミング言語(JLS§8.8)で書かれたすべてのコンストラクタは、特別な名前
<init>
を持つインスタンス初期化メソッドとして現れます。
そのため、JVMは クラスまたはインタフェースの初期化メソッド を初期化し、実際のコンストラクタである インスタンスの初期化メソッド は初期化しません。そのため、メインメソッドを呼び出す前にインスタンスが作成されていないことが暗黙のうちに含まれているため、メインメソッドはJVM仕様で静的である必要があることを言及する必要はありません。
キーワード 'static'はメインメソッドをクラスメソッドにし、クラスメソッドはそのコピーを1つだけ持ち、全員が共有できると思います。また、参照用のオブジェクトは必要ありません。そのため、ドライバクラスがコンパイルされるとmainメソッドが呼び出されます。 (私はちょうどJavaのアルファベットレベルにいる、私が間違っているならごめんなさい)
public
キーワードはアクセス修飾子であり、これを使うとプログラマはクラスメンバの可視性を制御できます。クラスメンバの前にpublic
がある場合、そのメンバは、それが宣言されているクラスの外側のコードでアクセスできます。
public
の反対はprivate
です。これはメンバーがそのクラスの外部で定義されたコードによって使用されるのを防ぎます。
この場合、main()
はpublic
として宣言する必要があります。これは、プログラムの起動時にクラス外のコードによって呼び出される必要があるためです。
キーワードstatic
を使用すると、クラスの特定のインスタンスをインスタンス化しなくてもmain()
を呼び出すことができます。 main()
はオブジェクトが作られる前にJavaインタプリタによって呼び出されるのでこれは必要です。
キーワードvoid
は単にmain()
が値を返さないことをコンパイラに伝えます。
それは単なる慣例です。それが慣例であるならば、JVMは確かに非静的なmainメソッドを扱うことができます。結局のところ、あなたのクラスに静的な初期化子を定義し、main()メソッドに到達する前に無数のオブジェクトをインスタンス化することができます。
static - JVMがmainメソッドを呼び出すとき、呼び出されているクラスに存在するオブジェクトが存在しないため、クラスからの呼び出しを許可するにはstaticメソッドが必要です。
あらゆるアプリケーションへの真の入り口は、静的メソッドです。 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()
メソッドのシグネチャをリストすることを要求することによって複雑さを生み出します。
まとめると、static void main()
を指定すると、振る舞いをメソッドに入れるという原則に従いながら、最も複雑さの少ない仕様が作成されます 。それ自体がクラスのインスタンスを構築し、インスタンスメソッドを呼び出すmain()
メソッドを実装するのがどれほど簡単であるかを考えると、main()
をインスタンスメソッドとして指定することに実際的な利点はありません。
オブジェクトがインスタンス化される前にJVMがmainメソッドを呼び出すかどうかはわかりません...しかし、main()メソッドが静的である理由はもっと強力です。 、人)。それは " Person.main() "によってそれを呼び出します。おわかりのように、JVMはそれをクラス名で呼び出します。そのため、main()メソッドは、JVMからアクセスできるように静的でパブリックになっている必要があります。
お役に立てば幸いです。もしそうなら、コメントして私に知らせてください。
プログラムの mainメソッド には 予約語 static があり、これは静的コンテキストでの使用が許可されていることを意味します。コンテキストは、プログラムの実行中のコンピュータメモリの使用に関連しています。仮想マシンがプログラムをロードすると、静的コンテキストを作成し、プログラムとそのデータなどを格納するために コンピュータメモリ を割り当てます。 動的コンテキスト はある種の割り当てです。プログラムの実行中に、後で作られるメモリの。 mainメソッドを静的コンテキストで実行することが許可されていないと、プログラムは開始できません。
ランタイムではJVMはmainメソッドを呼び出すためのオブジェクトを作成せず、クラス名を使用して呼び出すことができる唯一のメソッドであるため、mainメソッドは常に静的である必要があるため、mainメソッドは常に静的である必要があります。
詳細については、このビデオをご覧ください: https://www.youtube.com/watch?v=Z7rPNwg-bfk&feature=youtu.be
Javaでstaticとして宣言されたメソッドはすべてクラス自体に属します。また、特定のクラスの静的メソッドには、Class_name.method_name();
のようなクラスを参照することによってのみアクセスできます。
そのため、静的メソッドにアクセスする前にクラスをインスタンス化する必要はありません。
そのため、main()メソッドはstatic
として宣言されているので、そのクラスのオブジェクトを作成しなくてもアクセスできます。
Mainメソッドが存在するクラスの名前でプログラムを保存しているので(またはプログラムが実行を開始する場所から、main()
method()を持たないクラスにも適用できます(上級レベル))。だから上記の方法で:
Class_name.method_name();
mainメソッドにアクセスできます。
簡単に言うと、プログラムがコンパイルされるとき、それは言及されたクラスで(すなわちプログラムの名前によって)_ main()
のようなString
引数を持つmain(String args[])
メソッドを検索し、最初からそれがありません。そのクラスをインスタンス化するためのスコープであるため、main()メソッドはstaticとして宣言されます。
public static voidキーワードは、Java仮想マシン(JVM)インタプリタがクラスのインスタンスを作成せずにプログラム(public)を起動するためにプログラムのmainメソッドを呼び出すことができ、プログラムからデータが返されないことを意味します。終了時のJava VMインタプリタ(void)。
静的メソッドはオブジェクトを必要としません。直接実行されるのでメインが直接実行されます。
その背後には単純な理由があります。それは、オブジェクトが静的メソッドを呼び出す必要がないためです。非静的メソッドの場合、Java仮想マシンは最初にオブジェクトを作成し、次にmain()メソッドを呼び出します。
ここで見ることができるようにそれは単なる慣例です。
メソッド はpublicおよびstatic として宣言する必要があります。値を返してはいけません。また、String配列をパラメータとして使用する必要があります。デフォルトでは、最初のオプションではない引数は呼び出されるクラスの名前です。完全修飾クラス名を使用する必要があります。 -jarオプションが指定されている場合、最初のオプションではない引数は、アプリケーションのクラスファイルとリソースファイルを含むJARアーカイブの名前で、起動クラスはMain-Classマニフェストヘッダーで示されます。
http://docs.Oracle.com/javase/1.4.2/docs/tooldocs/windows/Java.html#description
Java.Sun.com から(このサイトにはもっと情報があります):
Mainメソッドは静的で、最初にコントロールクラスのインスタンスを作成せずにJava VMインタプリタにクラスを起動する方法を提供します。コントロールクラスのインスタンスは、プログラムの起動後にmainメソッドで作成されます。
私が理解していることは、他の静的メソッドと同じように、関連するクラスのインスタンスを作成せずにmainメソッドを呼び出すことができ、プログラム内の他のものよりも先に実行できるということです。静的でない場合は、呼び出す前にオブジェクトをインスタンス化する必要があります。これは、「鶏と卵」の問題を引き起こすためです。メインメソッドは、通常、プログラムの最初にオブジェクトをインスタンス化するために使用するものです。
基本的に、オブジェクトに関連したタスクを実行していないデータメンバーとメンバー関数をSTATICにします。そしてmainメソッドの場合、mainメソッドはオブジェクトを作成しているかどうかにかかわらず常に実行されるため、objectとは関係がないのでSTATICとして作成しています。
Mainメソッドではインスタンス化が行われないため、mainメソッドの静的キーワードWordが使用されます。しかし、mainメソッドでは静的キーWordを使用しているため、呼び出しではなくオブジェクトが構築されます。 jvmでは、クラスのロード時にコンテキストメモリが作成されます。すべての静的メンバがそのメモリ内に存在します。メインスタティックを作成すると、メモリ内になり、jvm(class.main(..))からアクセスできるようになるため、ヒープを作成する必要もなくmainメソッドを呼び出すことができます。