Javamain
メソッドのメソッド シグネチャは次のとおりです。
public static void main(String[] args) {
...
}
このメソッドが静的でなければならない理由はありますか?
これは単なる慣習です。実際、main() という名前と渡される引数でさえ、純粋に慣例です。
java.exe (または Windows では javaw.exe) を実行すると、実際に起こっているのは、いくつかの Java Native Interface (JNI) 呼び出しです。これらの呼び出しは、実際には JVM である DLL をロードします (そうです - java.exe は JVM ではありません)。JNI は、仮想マシンの世界と C、C++ などの世界を橋渡しする必要があるときに使用するツールです。逆もまた真です。(少なくとも私の知る限りでは)実際にJNI を使用せずに実行されている JVM。
基本的に、java.exe は、コマンド ラインを解析し、JVM に新しい String 配列を作成してこれらの引数を保持し、main() を含むものとして指定したクラス名を解析し、JNI 呼び出しを使用してmain() メソッド自体を呼び出してから、main() メソッドを呼び出し、新しく作成された文字列配列をパラメーターとして渡します。これは、Java からリフレクションを使用する場合と非常によく似ています。代わりに、紛らわしい名前のネイティブ関数呼び出しを使用するだけです。
独自のバージョンの java.exe (ソースは JDK とともに配布されます) を作成し、まったく異なることを実行させることは完全に合法です。実際、Java ベースのすべてのアプリで私たちが行っていることはまさにそれです。
各 Java アプリには独自のランチャーがあります。主にこれを行うのは、独自のアイコンとプロセス名を取得するためですが、物事を進めるために通常の main() 呼び出し以外に何かを実行したい場合に便利です (たとえば、あるケースでは、 COM の相互運用性を考慮し、文字列配列の代わりに COM ハンドルを main() に実際に渡します)。
つまり、長短: 静的である理由は、便利な b/c です。「メイン」と呼ばれる理由は、それが何かでなければならず、main() が C の昔の時代に行われたものである (そして当時、関数の名前が重要だった) ためです。java.exe では、クラス (java com.mycompany.Foo.someSpecialMain) だけでなく、完全修飾されたメイン メソッド名を指定することもできたと思いますが、IDE で ' を自動検出するのが難しくなります。プロジェクト内の起動可能なクラス。
メソッドは静的です。そうしないとあいまいさが生じるためです。どのコンストラクターを呼び出す必要がありますか? 特に、クラスが次のようになっている場合:
public class JavaClass{
protected JavaClass(int x){}
public void main(String[] args){
}
}
JVM は を呼び出す必要がありますnew JavaClass(int)
か? 何のために渡す必要がありx
ますか?
そうでない場合、JVM はJavaClass
コンストラクター メソッドを実行せずにインスタンス化する必要がありますか? クラス全体が特殊なケースになるため、そうすべきではないと思います-初期化されていないインスタンスがあり、呼び出される可能性のあるすべてのメソッドでそれを確認する必要がある場合があります。
エントリ ポイントが呼び出される前に JVM がクラスをインスタンス化する必要があるのは理にかなっているという点では、エッジ ケースとあいまいさが多すぎます。main
それが静的な理由です。
なぜmain
常にマークされているのかわかりませpublic
ん。
main
C ++、C#、およびJavaのメソッドは静的です。
これは、オブジェクトをインスタンス化することなくランタイムエンジンから呼び出すことができるため、本体のコードがmain
残りの作業を行います。
これが Java 言語の設計方法であり、Java 仮想マシンの設計および作成方法です。
第 12 章実行 - セクション 12.1.4 Invoke 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);
... ...
static
アプリケーションのエントリ ポイントとしては必要ない、という単純なふりをしましょう。
アプリケーション クラスは次のようになります。
class MyApplication {
public MyApplication(){
// Some init code here
}
public void main(String[] args){
// real application code here
}
}
main
オブジェクト指向では、コンストラクターはインスタンスが適切に初期化されていることのみを確認するため、コンストラクターコードとメソッドの区別が必要です。初期化後、インスタンスは目的の「サービス」に使用できます。完全なアプリケーション コードをコンストラクターに入れると、それが台無しになります。
したがって、このアプローチでは、アプリケーションで3 つの異なるコントラクトが強制されます。
main
abstract
。そうしないと、JVM はそれをインスタンス化できませんでした。一方static
、アプローチでは1 つのコントラクトのみが必要です。
main
方法が必要です1。ここでは、abstract
コンストラクターも複数も重要ではありません。
Java はユーザーにとって単純な言語になるように設計されているため、アプリケーションのエントリ ポイントも1 つのコントラクトを使用する単純な方法で設計されており、 3 つの独立した脆弱なコントラクトを使用する複雑な方法で設計されていないことは驚くべきことではありません。
注意: この議論は、JVM 内または JRE 内の単純さに関するものではありません。この議論は、ユーザーにとっての単純さに関するものです。
そうでない場合、複数あるコンストラクターを使用する必要がありますか?
Java言語仕様には、Javaプログラムの初期化と実行に関する詳細情報があります。
mainメソッドが呼び出される前は、オブジェクトはインスタンス化されません。staticキーワードがあるということは、最初にオブジェクトを作成せずにメソッドを呼び出すことができることを意味します。
そうしないと、実行するオブジェクトのインスタンスが必要になるためです。ただし、通常はmain()関数(ブートストラップ)のタスクであるため、最初にオブジェクトを作成せずに最初から呼び出す必要があります。通常、これらの引数/プログラムパラメータを使用して、引数を解析し、オブジェクトを作成します。
これらのことをもっと簡単に説明しましょう。
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
。
これは単なる慣例ですが、おそらく他の方法よりも便利です。静的メインでは、Javaプログラムを呼び出すために知っておく必要があるのは、クラスの名前と場所だけです。静的でない場合は、そのクラスをインスタンス化する方法を知っているか、クラスに空のコンストラクターが必要です。
アプレット、ミッドレット、サーブレット、およびさまざまな種類のBeanが構築され、ライフサイクルメソッドが呼び出されます。mainの呼び出しは、メインクラスに対して行われるすべてのことであるため、複数回呼び出されるオブジェクトに状態を保持する必要はありません。mainを別のクラスに固定するのはごく普通のことです(ただし、良いアイデアではありません)。これにより、クラスを使用してメインオブジェクトを作成する際に邪魔になります。
メイン メソッドが静的でない場合は、プログラムの外部からメイン クラスのオブジェクトを作成する必要があります。どのようにそれをしたいですか?
それは単なる慣習です。JVM は、非静的なメイン メソッドが規則であった場合、確実に処理できます。結局のところ、クラスで静的初期化子を定義し、main() メソッドに到達する前に無数のオブジェクトをインスタンス化できます。
最近、同様の質問が Programmers.SE に投稿されました。
エントリ
Application
ポイントが適切なコンストラクタ?
TL;DR受け入れられた回答の一部は、
Javaでは、その理由
public static void main(String[] args)
は
- ゴスリングが欲しかった
- (Java ではなく) C の経験がある人によって書かれたコード
- NeWSでPostScriptを実行するのに慣れている人が実行する
C# の場合、推論は推移的に似ています。言語設計者は、プログラム エントリ ポイントの構文を、Java 出身のプログラマーにとって使い慣れたものに保ちました。C# アーキテクトのAnders Hejlsberg が言うように、...C# での私たちのアプローチは、単純に代替手段を提供することでした... Java プログラマーに...
...
main() は静的です。アプリケーションのライフサイクルのその時点では、オブジェクトがまだインスタンス化されていないため、アプリケーション スタックは本質的に手続き型です。
それは白紙の状態です。この時点で、オブジェクトが宣言されていなくても、アプリケーションは実行されています (手続き型 AND OO コーディング パターンがあることを思い出してください)。開発者は、オブジェクトのインスタンスを作成し、コンパイルされたコードに依存することで、アプリケーションをオブジェクト指向ソリューションに変換します。
オブジェクト指向が素晴らしい理由は何百万もあります。ただし、ほとんどの VB 開発者がコードで「goto」などのキーワードを定期的に使用していた時代は終わりました。「goto」は VB の手続き型コマンドで、対応するオブジェクト指向のメソッド呼び出しに置き換えられます。
静的エントリ ポイント (メイン) を純粋な自由と見なすこともできます。オブジェクトをインスタンス化し、そのインスタンスのみを実行時に提示できるほど Java が異なっていた場合、手続き型アプリを作成する以外に選択肢はありません。Java では想像を絶するように聞こえるかもしれませんが、手続き型アプローチを必要とする多くのシナリオが存在する可能性があります。
これはおそらく非常にあいまいな返信です。「クラス」は相互に関連するコードの集まりにすぎないことを忘れないでください。「インスタンス」は、そのクラスの孤立した、生きて呼吸している自律的な世代です。
キーワード「static」はメインメソッドをクラスメソッドにし、クラスメソッドにはそのコピーが1つしかなく、すべてで共有できると思います。また、参照用のオブジェクトは必要ありません。そのため、ドライバー クラスがコンパイルされると、メイン メソッドを呼び出すことができます。(私はJavaのアルファベットレベルです。間違っていたらごめんなさい)
キーワードはpublic
アクセス修飾子であり、プログラマーがクラスメンバーの可視性を制御できるようにします。クラスメンバーの前にが付いているpublic
場合、そのメンバーには、宣言されているクラスの外部のコードからアクセスできます。
の反対public
は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()
メソッドのシグネチャをリストするよう仕様に要求することで、複雑さが生じます。
要約すると、を指定するstatic void main()
と、動作をメソッドに配置するという原則に従いながら、複雑さを最小限に抑えた仕様が作成されます。main()
それ自体がクラスのインスタンスを構築し、インスタンス メソッドを呼び出すメソッドを実装するのがいかに簡単かを考えると、インスタンス メソッドmain()
として指定することに実際の利点はありません。
プロトタイプは、 JLSpublic static void main(String[])
で定義された規則です。
メソッド 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>
、引数を取らず、無効です。
また、クラスまたはインターフェイスの初期化メソッドは、次のように定義されたインスタンスの初期化メソッドとは異なります。
Java 仮想マシンのレベルでは、Java プログラミング言語 (JLS §8.8) で記述されたすべてのコンストラクターは、特別な名前を持つインスタンス初期化メソッドとして表示されます
<init>
。
したがって、JVMは、実際にはコンストラクターであるインスタンス初期化メソッドではなく、クラスまたはインターフェイスの初期化メソッドを初期化します。そのため、メイン メソッドを呼び出す前にインスタンスが作成されないという事実によって暗示されているため、メイン メソッドは JVM 仕様で静的でなければならないことに言及する必要はありません。
public static void キーワードは、Java 仮想マシン (JVM) インタープリターがプログラムの main メソッドを呼び出して、クラスのインスタンス (静的) を作成せずにプログラム (public) を開始できること、およびプログラムが Java VM インタープリターにデータを返さないことを意味します。 (無効) 終了時。
オブジェクトがインスタンス化される前にJVMがメインメソッドを呼び出すかどうかはわかりません...しかし、main()メソッドが静的である理由はもっと強力な理由があります...JVMがクラスのメインメソッドを呼び出すとき(たとえば、 人)。" Person.main() "で呼び出します。ご覧のとおり、JVM はそれをクラス名で呼び出します。そのため、main() メソッドは、JVM からアクセスできるように static かつ public である必要があります。
それが役に立ったことを願っています。もしそうなら、コメントで教えてください。
メイン メソッドではインスタンス化が行われないため、メイン メソッドの static キーワードが使用されます。ただし、呼び出しではなくオブジェクトが構築されるため、メイン メソッドで static キーワードを使用します。jvm コンテキストでは、クラスがロードされるとメモリが作成されます。そして、すべての静的メンバーがそのメモリに存在します。メインを静的にすると、メモリ内になり、jvm (class.main(..)) にアクセスできるようになるため、ヒープを作成する必要さえなく、メイン メソッドを呼び出すことができます。
その背後にある単純な理由は、オブジェクトが静的メソッドを呼び出す必要がないためです。非静的メソッドの場合、Java 仮想マシンは最初にオブジェクトを作成してから main() メソッドを呼び出します。これにより、余分なメモリ割り当ての問題が発生します。
ここでわかるように、これは単なる慣例です。
メソッドは public および static として宣言する必要があり、値を返してはならず、パラメーターとして String 配列を受け入れる必要があります。デフォルトでは、最初の非オプション引数は呼び出されるクラスの名前です。完全修飾クラス名を使用する必要があります。-jar オプションが指定されている場合、オプション以外の最初の引数は、アプリケーションのクラス ファイルとリソース ファイルを含む JAR アーカイブの名前であり、起動クラスは Main-Class マニフェスト ヘッダーによって示されます。
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description
プログラムのメイン メソッドには予約語 staticがあります。これは、静的コンテキストで使用できることを意味します。コンテキストは、プログラムの実行中のコンピューター メモリの使用に関連しています。仮想マシンがプログラムをロードすると、その静的コンテキストが作成され、プログラムとそのデータなどを格納するためにコンピュータメモリが割り当てられます。プログラム。main メソッドが静的コンテキストでの実行を許可されていない場合、プログラムは開始できません。
基本的に、オブジェクトに関連するタスクを実行していない DATA MEMBERS と MEMBER FUNCTIONS を STATIC として作成します。また、main メソッドの場合は、オブジェクトを作成しているかどうかに関係なく main メソッドが常に実行されるため、オブジェクトとは関係がないため、STATIC として作成しています。
静的メソッドはオブジェクトを必要としません。直接実行されるため、メインは直接実行されます。
java.sun.comから(サイトに詳細情報があります) :
main メソッドは static であり、最初にコントロール クラスのインスタンスを作成せずに Java VM インタープリターがクラスを開始できるようにします。コントロール クラスのインスタンスは、プログラムの開始後にメイン メソッドで作成されます。
私の理解では、メイン メソッドは、他の静的メソッドと同様に、関連付けられたクラスのインスタンスを作成せずに呼び出すことができ、プログラム内の他の何よりも先に実行できるという単純なものでした。静的でない場合は、呼び出す前にオブジェクトをインスタンス化する必要があります。これにより、「鶏が先か卵が先か」という問題が発生します。これは、main メソッドが通常、プログラムの最初にオブジェクトをインスタンス化するために使用するものであるためです。
static は、このメソッドがクラス メソッドであり、クラスのオブジェクトを必要とせずに呼び出されることを示します。
Java で main() が静的である理由はよくある質問です。
回答: Java では、JVM によって main() から実行が開始されることがわかっています。その時点で JVM が main() を実行すると、main() を含むクラスはインスタンス化されないため、そのオブジェクトの参照なしに非静的メソッドを呼び出すことはできません。そのため、それを呼び出すために静的にしました。これにより、クラスローダーは、JVM が直接呼び出すことができる JVM コンテキストメモリ空間にすべての静的メソッドをロードします。
main() および Java からのプログラムの実行開始は、オブジェクトが main() 内で宣言されている純粋なオブジェクト指向プログラムであるため、オブジェクトの作成前に main() が呼び出されるため、main() が非静的である場合はそれを呼び出しますstatic はオブジェクトの必要がないことを意味するため、オブジェクトが必要になります........
静的メンバーは特定のクラスの一部ではなく、そのメイン メソッドはそのオブジェクトを作成する必要はありませんが、他のすべてのクラスを引き続き参照できるためです。