質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

オブジェクト言語であるJavaはなぜmainメソッドから含むクラスから起動されるようになっているのですか?

解決済

回答 6

投稿

  • 評価
  • クリップ 2
  • VIEW 3,949

mr0237

score 162

JAVAのオブジェクト指向を勉強・練習している者です。

説明が下手ですいませんが、「スッキリわかるJava入門 第2版 (スッキリシリーズ) 」(P304~P305)にて

「mainメソッドを持つクラスがないと、その他のクラスを起動して動かすことはできない」と書かれていたのですが、
なぜmainメソッドを含むクラスがないと、動かすことができないのですか?

mainメソッドを含むクラス等は現実世界に模している訳でもないし、インスタンス化して利用するものでもないと思うのですが
なぜJavaはmainメソッドから含むクラスから起動されるようになっているのですか?

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+15

もし、プログラムの各命令文をトップレベルに並べて書くことができるのであれば、上から順番に実行するだけで済むでしょう。実際にそのような言語も数多くあります(特にスクリプト言語)。

では、Javaのような必ずクラスを作ってその中にメソッドを作るような場合や、Cのように各命令文は関数の中にしか書けないような言語の場合はどうなるでしょうか?コードに存在するのは、クラスやメソッド(関数)の定義だけで、それがすぐさま実行されるわけではありません。こんな時に、一体どこから始めれば良いのでしょうか?

その最初に始めるところをエントリーポイントと言います。Javaではクラスのsaticなmainというメソッドをエントリーポイントにし、javaコマンドで実行時に指定したクラスのstaticなmainというメソッドから始めると言語の仕様として決めました。なぜmainという名前なのかはJavaを作った人に聞かないとわからないでしょう。

なお、なぜstaticなメソッドなのかは、Javaにはオブジェクトそのものを定義する方法がなく、起動時にインスタンスが存在しないからです。クラスしか無いため、staticなメソッドを使うしかありません。Scalaという同じJava VMを使う言語では、オブジェクトそのものを作れるため、オブジェクトのメソッドとしてmainを定義するようになっています。(それ以外にも、Scalaをスクリプトとして実行した場合は、トップレベルがmainとみなされます)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+4

エントリポイントだから、です。

mainメソッドを含むクラス等は現実世界に模している訳でもないし、インスタンス化して利用するものでもない

↑それがなぜ、不要であることを意味すると思えるのでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

こんにちは。

なぜJavaはmainメソッドから含むクラスから起動されるようになっているのですか?

Javaの設計者がそのように定めたからと思います。
なぜそのような方法を選択したのか?は議論の余地がありますね。

Javaが参考にしたC++はmain()関数がグローバルな関数で(事実上)1つだけ存在します。
しかし、Javaにはグローバル関数がありません。①mainと言う特別なグローバル関数を用意する、②mainクラスみたいな特別なクラスを設ける、③全てのクラスがmainメソッドを持ちうる等の選択肢が考えられます。
Javaへの特別な仕組みの導入を最小限で済むのは③のような気がします。

なお、main(プログラムの開始点)が存在しない設計も理論的にはありえますが、意味ないでしょう。何らかの方法でプログラムの実行を開始できないと、それは永遠にプログラムとしての役に立ちません。そして、起動した時点で開始するのは妥当な設計と思います。実際の動作を遅らせたい場合は「遅らせるプログラム」を書けばよいだけですから。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

趣味でプログラミングをやっています。
なので話半分ぐらいで読んでください。

理由はエントリポイント ( Entry Point ) だからです。

しかも、Java, Python, Ruby, Perlは、

何かしらのソフトやプラットフォーム? が動かします。

C/C++ 等で作った場合は、

$main file.txt > result.txt

みたいにしてコマンドライン引数で渡すのと同じです。

実際に Javaで考えて見ましょうか。

( Program.class を動かすとします。 )

$java -classpath C:\test\lib Program

みたいにしますね。

単純なのだと、

$java Program

という感じですね。

これって、C/C++のやつと比較すると、

java = 実行ファイル

Program(.class) = コマンドライン引数でのファイル指定

と読めますね。

なので、たぶん、

Java.exe (?) が コマンドライン引数として渡された クラスファイル Program.class を 同時に渡されたクラスパスを読み込んで、字句解析かなんかをしながら処理しているのだと思います。

Aさんに レシピを渡して (それに使う材料もあれば同時に渡して) 作ってもらうっていう感じでしょうか。

で、Java.exe が読み込んで 行う基本的な処理を mainメソッドに書かれていますからそこを読み込めばいいのです。

たぶん、そういう理由もあると思います。

あとは歴史的なものかと。

CやC++といった言語では main関数 ( mainメソッドに相当 ) があります。

そのなごりで mainメソッドがあるとか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

"java main static 理由"
で google 検索すると、いろいろ情報が得られると思います。

検索結果からの紹介

...
Java コンパイラが出力するのは、クラスファイル(.class)です。これがバイトコード。java コマンドでは、エントリーポイントを指定してクラスファイルを実行します。

C コンパイラ(リンカ)が出力する実行可能ファイルにもエントリーポイントというものがあります。エントリーポイントとは、OS がプログラムファイルをメモリに読み込んで整頓したあと、最初に実行する(制御を渡す言う)命令のアドレスです。皆さんはそれが、main() だと思っていませんか?それは違います。C コンパイラが吐き出す実行プログラムのエントリーポイントは crt0 という特殊なライブラリの中に有り、そこから main が呼ばれるのです。よく考えてみましょう。main() は int 型の値を返しますが、OS にどうやって返しているのでしょうか?そういう低レベルの仕事をするライブラリが必要なのです。それが crt0 (C Runtime 0)です。(また話が逸れてしまいました)

Java インタープリタは、コマンドラインに指定されたクラスのクラスファイルをメモリに読み込み、そのクラスの main() メソッドを実行します。

さて、では Java インタープリタ はどうやってクラスファイルを探すのでしょうか?それは、-cp コマンドラインオプション、あるいは、CLASSPATH 環境変数で指定されたディレクトリあるいは zip/jar ファイルの中を探しに行きます。
...

...
Javaの規則として、指定したクラスのstaticなmainという名前のメソッドを呼び出すという動作を行います。
ここで、呼び出したクラスのインスタンス化は行っていません。そのため、ちょっと理解しづらいプログラムの書き方をしなければなりません。たとえば、Personalityクラスにmainメソッドを追加して、アプリケーションとして稼働させるには、次のように記述します。mainメソッドの引数や返り値についても規定がなされていて、定義はその通りに書かないといけません。
...
この最後のmainメソッドのプログラムは理解しづらいと思います。Personalityクラスの中で、なぜPersonalityのインスタンスを生成しないといけないのかということは理解しづらいでしょう。ここでは、mainは特別な存在だと思ってください。ここが、Javaのアプリケーションとオペレーティングシステムの架け橋になるのです。最初に呼ばれたmainメソッドだけ、ある意味、妙な記述をしないといけないということです。
...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

エントリーポイントや、public static である理由は既に書かれているので割愛します。

main という名にした理由の推測ですが、C言語やC++に似せたからだと思います。

例えば、ScalaというJava VirtualMachine上で動作する言語があります。

Scalaではmainメソッドの代わりに、

object Sample extends Application {
// この{}にロジックを記述すると、Javaのmaimメソッドの中身にロジックを書いたのと同じように動く(このブロックはSampleオブジェクトのコンストラクターでもあります)
}

と記述することが出来ます。
また、上記の代わりに、Javaのように

object Sample {
def main(args: Array[String]): Unit = {
// ここにmaimメソッドの中身
}
}

とも記述することが出来ます。

何が言いたいかというと、結局は、言語の設計の問題で、恐らくは、設計当時に存在していて、主流だったり、参考にした言語(C言語やC++)に似せただけではないかと思います。
似せることによって、それらを使って開発している開発者に対しての敷居を下げることが出来るからです。

ScalaのApplicationトレイト(Javaのinterfaceのようなもの)を、object(Javaのクラスのインスタンス同じなのですが、必ずシングルトンパターンのインスタンスとなる特殊なもの)にJavaでいう継承(Scalaではトレイトも実装ではなく継承と呼びます)し、そのコンストラクターがエントリーポイントとなる!と、設計時に決めてしまえば、ScalaではApplicationトレイトをextendsするのかとなります。
ただ、Javaからの移行をさせたいときには、mainメソッドを書きます!といったほうがなじみ深くて取っ掛かりやすいのではないでしょうか?
だから、Scalaにもmainメソッドが存在しているのだと思います。
Javaも、それと同じように、C言語やC++に倣ってmainメソッドとしたのだと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Javaに関する質問
  • オブジェクト言語であるJavaはなぜmainメソッドから含むクラスから起動されるようになっているのですか?