web-dev-qa-db-ja.com

なぜコンストラクタではなく、JavaおよびC#の静的メインメソッドですか?

(特に)JavaとC#が、アプリケーションインスタンスをで表すのではなく、静的メソッドをエントリポイントとして持つことにした理由について、プライマリまたはセカンダリソースからの明確な答えを探しています。 Applicationクラスのインスタンス(エントリポイントは適切なコンストラクタです)。


私の以前の研究の背景と詳細

これは以前に尋ねられました。 残念ながら、既存の回答は単に 質問をすること です。特に、以下の回答は不正確であると私が思うため、私には満足しません。

  • コンストラクタがオーバーロードされている場合はあいまいになります。–実際、C#(およびCとC++)はMainに異なる署名を許可するため、同じ可能性がありますあいまいさが存在し、対処されます。
  • staticメソッドは、オブジェクトをインスタンス化できないため、初期化の順序が明確であることを意味します。–これは実際には間違っています。一部のオブジェクトare以前にインスタンス化されている(たとえば、静的コンストラクタ内)。
  • そのため、親オブジェクトをインスタンス化する必要なく、ランタイムによって呼び出すことができます。–これはまったく答えではありません。

これが正当で興味深い質問だと思う理由をさらに正当化するために:

  • 多くのフレームワークdoは、クラスを使用してアプリケーションを表し、コンストラクタをエントリポイントとして使用しています。たとえば、 VB.NETアプリケーションフレームワーク は、専用のメインダイアログ(およびそのコンストラクタ)をエントリポイントとして使用します。1

  • どちらもJavaも技術的にもC#needmain method。 さて、C#はコンパイルしますが、Javaでもそうではありません。どちらの場合も実行には必要ありません。したがって、これは技術的な制限ではないようです。そして、最初の段落で述べたように、単なる規則では、JavaおよびC#の一般的な設計原則とは奇妙に合わないようです。

明確にするために、静的なmainメソッドを持つことに特定の欠点はありません、それは単に明確にodd、その背後に何らかの技術的根拠があるのか​​と思いました。

単なる推測ではなく、一次または二次ソースからの明確な回答に興味があります。


1 これを傍受する可能性があるコールバック(Startup)がありますが。

55
Konrad Rudolph

TL; DR

Javaでは、public static void main(String[] args)の理由は

  1. ゴスリング 欲しかった
  2. c(Javaではない)の経験者が作成したコード
  3. PostScriptNeWS で実行していた人が実行する

http://i.stack.imgur.com/qcmzP.png


C#の場合、推論はいわば推移的に類似しています。言語デザイナーは、 プログラムのエントリポイント 構文をJavaから来たプログラマに馴染みのあるものに保ちました。 C#のアーキテクト Anders Hejlsbergによると、

... C#を使用したアプローチは、単にJavaプログラマに代わるものを提供することです...

ロングバージョン

上に拡張し、退屈な参照でバックアップ。

JavaターミネーターHasta la Vista Baby!

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歴史役立つかもしれないと思いました(しかし役に立たないことが判明しました)。

  • 私の解釈:
    実行はVM仕様のみによって管理され、
    Java言語とは関係がないことを明示的に宣言します
    => [〜#〜] jls [〜#〜] およびすべてのJava言語を無視しても問題ありません

ゴスリング:Cとスクリプト言語の妥協点...

上記に基づいて、私はJVM履歴をWebで検索し始めました。役に立たなかった、結果のゴミが多すぎる。

次に、ゴスリングの伝説を思い出し、検索をゴスリングJVM履歴に絞り込みました。

ユーレカ! JVM仕様がどうなったか

James Goslingは、JVM言語サミット2008の基調講演で、Javaの作成、C言語とスクリプト言語の妥協点について説明しています。

  • 私の解釈:
    作成の瞬間に、
    Cとスクリプトは最も重要な影響と考えられています。

    VM仕様2.17.1ですでにスクリプトにうなずき、
    コマンドライン引数は十分に説明していますString[] args
    しかしstaticmainはまだありません。さらに掘り下げる必要があります...

これを入力しているときに注意してください-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[]があり、これらを使用してコマンドライン引数を処理できます...

近づいていますか?あなたが賭ける。上記の引用からの「メイン」リンクをたどる価値もあります。

主な機能は、プログラムが実行を開始する場所です。これは、プログラムの機能の高レベルの構成を担当し、通常、プログラムの実行時にプログラムに与えられたコマンド引数にアクセスできます。

  • 私の解釈:
    C開発者が快適に使用できるようにするには、プログラムのエントリポイントをmainにする必要があります。
    また、Javaではクラス内にメソッドが必要であるため、Class.main
    できるだけ近づく:静的呼び出し、クラス名とドットだけ、
    コンストラクタはありません-Cはそのようなことを何も知りません。

    これもtransitivelyを考慮してC#に適用されます
    Javaから簡単に移行できるという考え方。

Java SEから来た人たちがHello Worldを書こうとしているStack Overflowの質問を検索して確認するよう、親切なプログラムのエントリポイントが問題ではないと考える読者を歓迎しますJava ME MIDP。注 MIDPエントリポイント にはmainstaticもありません。

結論

上記に基づいて、私はstaticmainおよび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からのシンボリック参照。

38
gnat

それは漠然と私を虐待しているように感じます。コンストラクターは、オブジェクトの初期化に使用されます。コンストラクターはオブジェクトをセットアップし、それを作成したコードで使用されます。

基本的な使用機能をコンストラクター内に配置し、コンストラクターが外部コードで作成したオブジェクトを実際に使用しない場合は、OOPの原則に違反しています。基本的に、明らかな理由もなく、本当に奇妙なことをしています。

なぜとにかくそれをしたいのですか?

16
Mason Wheeler

Javaの場合、理由は簡単だと思います。Javaを開発するとき、開発者は、言語を学ぶほとんどの人がC/C++を事前に知っていることを知っていました。

したがって、Javaは、Smalltalkの代わりにC/C++によく似ているだけでなく、C/C++からの特異性も引き継ぎました(8進整数リテラルを考えるだけです)。c/ c ++は両方ともmainメソッド、Javaに対して同じことを行うことは、その観点から意味があります。

彼らが8進整数リテラルを追加した理由について、この線に沿って何か言ったことを覚えていると確信しています。いくつかのソースを見つけることができるかどうか確認します:)

9
Voo

まあ、そこには無限ループを実行する主要な関数がたくさんあります。このように動作する(オブジェクトが構築されない)コンストラクタは、私には奇妙に見えます。

このコンセプトには面白いことがたくさんあります。生まれないオブジェクト、死ぬために生まれたオブジェクト(それらはコンストラクターですべての仕事をしているため)の上で実行されるロジック、...

OOワゴンは単純なパブリックよりもはるかに破損するわけではありません(不明なものからアクセスする必要があるため)static(開始するためにインスタンスは必要ないため) )void main(エントリポイントであるため)?

単純でプレーンな関数のエントリポイントがJavaに存在するためには、publicおよびstaticが自動的に必要になります。 静的メソッドですが、結局のところ、必要なことを達成するために単純なエントリポイントという単純な関数に近づけることができます。

シンプルでプレーンな関数のエントリポイントをエントリポイントとして採用しない場合。構築するつもりのない構築者として奇妙に思われない次は何ですか?

6
pepper_chico

テスト中のクラスにmain()を追加することで、開発中にクラスのスタンドアロンテストをすばやく実行できます。

3
Graham Borland

私の理解では、主な理由は単純です。 SunはUnixマシンを販売するUnix企業であり、UnixはCの「main(args)」 バイナリを呼び出すための規約 が設計されたものです。

さらにJavaは、CおよびC++プログラマーが簡単にピックアップできるように明示的に設計されているため、単にCの規則を採用するだけでは十分ではありません。

すべてのクラスが呼び出しメソッドを持つことができる選択されたアプローチは、特に実行可能なjar内のMANIFEST.MFファイルのMain-Classlineと組み合わせて、非常に柔軟です。

0
user1249

どこかから始めなければならない。静的メインは、あなたが持つことができる最も単純な実行環境です-何のインスタンスも(JVMおよび単純な文字列パラメーター以外に)作成する必要はありません-したがって、最小限の手間で(そして可能性が低く)起動できます起動を妨げるコーディングエラーの例など)、他の多くの設定なしで簡単なことを行うことができます。

基本的にはKISSのアプリケーションです。

[そしてもちろん、主な理由は次のとおりです。なぜそうしないのですか?]

0
Daniel R Hicks