(特に)JavaとC#が、アプリケーションインスタンスをで表すのではなく、静的メソッドをエントリポイントとして持つことにした理由について、プライマリまたはセカンダリソースからの明確な答えを探しています。 Application
クラスのインスタンス(エントリポイントは適切なコンストラクタです)。
これは以前に尋ねられました。 残念ながら、既存の回答は単に 質問をすること です。特に、以下の回答は不正確であると私が思うため、私には満足しません。
Main
に異なる署名を許可するため、同じ可能性がありますあいまいさが存在し、対処されます。static
メソッドは、オブジェクトをインスタンス化できないため、初期化の順序が明確であることを意味します。–これは実際には間違っています。一部のオブジェクトare以前にインスタンス化されている(たとえば、静的コンストラクタ内)。これが正当で興味深い質問だと思う理由をさらに正当化するために:
多くのフレームワークdoは、クラスを使用してアプリケーションを表し、コンストラクタをエントリポイントとして使用しています。たとえば、 VB.NETアプリケーションフレームワーク は、専用のメインダイアログ(およびそのコンストラクタ)をエントリポイントとして使用します。1。
どちらもJavaも技術的にもC#needmain method。 さて、C#はコンパイルしますが、Javaでもそうではありません。どちらの場合も実行には必要ありません。したがって、これは技術的な制限ではないようです。そして、最初の段落で述べたように、単なる規則では、JavaおよびC#の一般的な設計原則とは奇妙に合わないようです。
明確にするために、静的なmain
メソッドを持つことに特定の欠点はありません、それは単に明確にodd、その背後に何らかの技術的根拠があるのかと思いました。
単なる推測ではなく、一次または二次ソースからの明確な回答に興味があります。
1 これを傍受する可能性があるコールバック(Startup
)がありますが。
Javaでは、public static void main(String[] args)
の理由は
C#の場合、推論はいわば推移的に類似しています。言語デザイナーは、 プログラムのエントリポイント 構文をJavaから来たプログラマに馴染みのあるものに保ちました。 C#のアーキテクト Anders Hejlsbergによると、 、
... C#を使用したアプローチは、単にJavaプログラマに代わるものを提供することです...
上に拡張し、退屈な参照でバックアップ。
VM Spec、2.17.1仮想マシンの起動
... Java仮想マシンに初期クラスを指定する方法はこの仕様の範囲外ですが、コマンドラインを使用するホスト環境では、クラスの完全修飾名が一般的ですコマンドライン引数として指定され、後続のコマンドライン引数は、メソッドmainへの引数として提供される文字列として使用されます。たとえば、SunのJava 2 SDK for Solarisを使用すると、コマンドライン
Java Terminator Hasta la Vista Baby!
Java仮想マシンを起動するには、クラス
Terminator
(名前のないパッケージ内のクラス)のmainメソッドを呼び出し、4つの文字列「Hasta」、「la」、「Vista」を含む配列を渡します。 「そして、「赤ちゃん!」...
...参照:付録:服、ブーツ、オートバイが必要です
...私たちの調査でいくつかの誤った痕跡を回避するのに役立ちます。
VM仕様、 1.2 Java仮想マシン
Java仮想マシンはJavaプログラミング言語を認識していません...
前の章を勉強しているときに上記のことに気づきました-1.1歴史役立つかもしれないと思いました(しかし役に立たないことが判明しました)。
上記に基づいて、私はJVM履歴をWebで検索し始めました。役に立たなかった、結果のゴミが多すぎる。
次に、ゴスリングの伝説を思い出し、検索をゴスリングJVM履歴に絞り込みました。
ユーレカ! JVM仕様がどうなったか
James Goslingは、JVM言語サミット2008の基調講演で、Javaの作成、C言語とスクリプト言語の妥協点について説明しています。
String[] args
static
とmain
はまだありません。さらに掘り下げる必要があります...これを入力しているときに注意してください-C、スクリプト、およびVM Spec 1.2をJavaの何もないものに接続しています-私はなじみのあるもののように感じます...オブジェクト指向はゆっくり亡くなる。 私の手を取り、動き続けてください私たちがもうすぐそこにいるので減速しないでください
キーノートスライドはオンラインで入手できます: 20_Gosling_keynote.pdf 。キーポイントのコピーに非常に便利です。
ページ3 Javaの先史 *私の考えを形作ったもの 9ページ NeWS *ネットワーク化された拡張可能なウィンドウシステム *スクリプトに基づくウィンドウシステム.... PostScript(!!) 16ページ 大きな(しかし静かな)目標: 「スクリプト」の感覚にどれだけ近づくことができるか... ページ19 元のコンセプト *物事のネットワークの構築 、すべてがスクリプトで構成された 言語 *(UNIXシェル、AppleScriptなど) 20ページ 羊の服を着た狼 *開発者を快適にするC構文 快適な
あはは! C syntaxを詳しく見てみましょう。
「こんにちは、世界」の例...
main() { printf("hello, world\n"); }
... mainという名前の関数が定義されています。 main 関数は、Cプログラムで特別な目的を果たします。ランタイム環境はmain関数を呼び出してプログラムの実行を開始します。
...メイン関数には実際には2つの引数
int argc
およびchar *argv[]
があり、これらを使用してコマンドライン引数を処理できます...
近づいていますか?あなたが賭ける。上記の引用からの「メイン」リンクをたどる価値もあります。
主な機能は、プログラムが実行を開始する場所です。これは、プログラムの機能の高レベルの構成を担当し、通常、プログラムの実行時にプログラムに与えられたコマンド引数にアクセスできます。
main
にする必要があります。Class.main
はJava SEから来た人たちがHello Worldを書こうとしているStack Overflowの質問を検索して確認するよう、親切なプログラムのエントリポイントが問題ではないと考える読者を歓迎しますJava ME MIDP。注 MIDPエントリポイント にはmain
もstatic
もありません。
上記に基づいて、私はstatic
、main
およびString[] args
がJavaおよびC#の作成の瞬間であり、 を定義するための最も合理的な選択であったと言いますプログラムのエントリポイント 。
VM仕様 2.17.1 を読むのはとても楽しかったです。
...コマンドライン
Java Terminator Hasta la Vista Baby!
Java仮想マシンを起動するには、クラス
Terminator
(名前のないパッケージ内のクラス)のmainメソッドを呼び出し、4つの文字列「Hasta」、「la」、「Vista」を含む配列を渡します。 "、および"赤ちゃん! "。後のセクションでさらに説明するロード、リンク、および初期化プロセスの例として、仮想マシンが
Terminator
を実行するために実行できる手順の概要を説明します。最初の試み...クラス
Terminator
がロードされていないことがわかりました...
Terminator
がロードされた後、mainを呼び出す前に初期化する必要があり、初期化する前に型(クラスまたはインターフェイス)を常にリンクする必要があります。リンク(2.17.3)には、検証、準備、および(オプションで)解決が含まれます...検証(2.12.17.3)は、ロードされた
Terminator
の表現が整形式であることを確認します...解決(2.12.17.3)は、クラス
Terminator
...からのシンボリック参照をチェックするプロセスです。
Terminator
からのシンボリック参照。
それは漠然と私を虐待しているように感じます。コンストラクターは、オブジェクトの初期化に使用されます。コンストラクターはオブジェクトをセットアップし、それを作成したコードで使用されます。
基本的な使用機能をコンストラクター内に配置し、コンストラクターが外部コードで作成したオブジェクトを実際に使用しない場合は、OOPの原則に違反しています。基本的に、明らかな理由もなく、本当に奇妙なことをしています。
なぜとにかくそれをしたいのですか?
Javaの場合、理由は簡単だと思います。Javaを開発するとき、開発者は、言語を学ぶほとんどの人がC/C++を事前に知っていることを知っていました。
したがって、Javaは、Smalltalkの代わりにC/C++によく似ているだけでなく、C/C++からの特異性も引き継ぎました(8進整数リテラルを考えるだけです)。c/ c ++は両方ともmainメソッド、Javaに対して同じことを行うことは、その観点から意味があります。
彼らが8進整数リテラルを追加した理由について、この線に沿って何か言ったことを覚えていると確信しています。いくつかのソースを見つけることができるかどうか確認します:)
まあ、そこには無限ループを実行する主要な関数がたくさんあります。このように動作する(オブジェクトが構築されない)コンストラクタは、私には奇妙に見えます。
このコンセプトには面白いことがたくさんあります。生まれないオブジェクト、死ぬために生まれたオブジェクト(それらはコンストラクターですべての仕事をしているため)の上で実行されるロジック、...
OOワゴンは単純なパブリックよりもはるかに破損するわけではありません(不明なものからアクセスする必要があるため)static(開始するためにインスタンスは必要ないため) )void main(エントリポイントであるため)?
単純でプレーンな関数のエントリポイントがJavaに存在するためには、publicおよびstaticが自動的に必要になります。 静的メソッドですが、結局のところ、必要なことを達成するために単純なエントリポイントという単純な関数に近づけることができます。
シンプルでプレーンな関数のエントリポイントをエントリポイントとして採用しない場合。構築するつもりのない構築者として奇妙に思われない次は何ですか?
テスト中のクラスにmain()
を追加することで、開発中にクラスのスタンドアロンテストをすばやく実行できます。
私の理解では、主な理由は単純です。 SunはUnixマシンを販売するUnix企業であり、UnixはCの「main(args)」 バイナリを呼び出すための規約 が設計されたものです。
さらにJavaは、CおよびC++プログラマーが簡単にピックアップできるように明示的に設計されているため、単にCの規則を採用するだけでは十分ではありません。
すべてのクラスが呼び出しメソッドを持つことができる選択されたアプローチは、特に実行可能なjar内のMANIFEST.MFファイルのMain-Class
lineと組み合わせて、非常に柔軟です。
どこかから始めなければならない。静的メインは、あなたが持つことができる最も単純な実行環境です-何のインスタンスも(JVMおよび単純な文字列パラメーター以外に)作成する必要はありません-したがって、最小限の手間で(そして可能性が低く)起動できます起動を妨げるコーディングエラーの例など)、他の多くの設定なしで簡単なことを行うことができます。
基本的にはKISSのアプリケーションです。
[そしてもちろん、主な理由は次のとおりです。なぜそうしないのですか?]