(java)「mainメソッドには戻り値がないが,void指定しないと仮想計算機にロードされない」のに「コンストラクタには戻り値がなく,戻り値の型指定をすると一般メソッドとして取り扱われる」規定になっているのはなぜでしょうか。「必ずvoid指定する」か「必ず型指定しない」のどちらかに統一してくれれば余計なことを覚えなくて済むのに。。。初学者なので表現に誤りがあるかもしれませんが,間違ってvoidを打ち込んで原因不明となることがよくあるので,よろしくお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2006/04/09 09:09:45
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:kishiro No.4

回答回数161ベストアンサー獲得回数4

ポイント100pt

質問者は、少し誤解されているようです。

http://www.y-adagio.com/public/standards/tr_javalang/index.h...

Java言語では

・コンストラクタ:「必ず型指定しない」

・メソッド:「必ず型指定が必要」

となっており、一貫性があります。

 

型が指定されているコンストラクタは存在しないし

逆に型が指定されていないメソッドも存在しません。

 

「コンストラクタには戻り値がなく,戻り値の型指定をすると一般メソッドとして取り扱われる」

というのは、単に

「クラスやコンストラクタと同じ名称のメソッドを定義できます」

と言い換えることができる。 

 

よって、たまたまクラス、コンストラクタ、メソッドの名称が

全く同じだったとしても、それぞれ異なる役割を果たします。

下記は名称が"Sample"だった場合の例です。

 

public class Sample {

  /** 表示する文言 */

  private String words_;

  /** メインメソッド */

  public static void main(String[] args) {

    //コンストラクタによって、インスタンス初期化

    Sample sample = new Sample();

    //メソッドによって、処理を実行

    sample.Sample();

  }

  /** コンストラクタ */

  public Sample() {

    words_ = "This is Sample !";

  }

  /** メソッド */

  public void Sample() {

    System.out.println(words_);

  }

}

id:Ryo9508

なるほど!確かに誤解をしておりました。メソッドは型指定を省略すればintかvoidになるのかと思っていました(必ず型指定をしていたので気づきませんでした)。型指定が有るか無いかで厳密に違うのですね。

2006/04/09 08:53:11

その他の回答5件)

id:tarchan No.1

回答回数200ベストアンサー獲得回数2

ポイント30pt

http://javafaq.jp/S002.html#S002-01

mainメソッドに戻り値がないことを表すためにvoidを指定します。

public static void main(String[] args)

void以外を指定すればオーバーロードした別のメソッドなので起動時に呼ばれることはなくなります。

id:Ryo9508

ありがとうございました。mainメソッドとコンストラクタでは使い方はまったく違いますが,「必ずvoid指定する」メソッドと「必ず型指定しない」メソッドとする理由が思いつかず,言語規定に一貫性が無いように思うのですが。。。

2006/04/08 22:17:00
id:ma-kanoh No.2

回答回数155ベストアンサー獲得回数4

ポイント30pt

http://www2.ocn.ne.jp/~notes/java/java17.html

ええと、まず「コンストラクタ」は「メソッド」ではありません。

「コンストラクタ」はクラスの初期化を担っています。

単にそれだけでしかありません。なぜそうなっているかといえば、

オブジェクト指向を言語仕様から実装しようとしたからだと

思えばいいのでは。「コンストラクタ」の動作としては正しいかと思います。

コンストラクタの戻り値は絶対に「その」クラスしか

ありえませんから。

ただし、main()メソッド(これは単なるメソッド)はオブジェクト指向からすると不思議なメソッドになってしまうので混乱するのでしょう。

main()メソットだけが例外だと考えればいいです。

よくでてくる関数が例外になるの?と思うでしょうが、、

Javaを使用していくと、あまりmain()使いませんので

気にしなかったりします。

ということで回答としては

  • (1)「コンストラクタ」はそのまま(何も指定しない)で正しい
  • (2)main()関数(メソットだけど)の方が例外である

と思ったほうがいいと思います。

id:Ryo9508

ありがとうございました。「そのようになっている」と思うしかないんでしょうね。

2006/04/09 08:07:03
id:quintia No.3

回答回数562ベストアンサー獲得回数71

ポイント30pt

すみませんが、明確な回答ではなくて質問の整理をさせてもらいます。

public class Object1 {
    public Object1() {
        System.out.println("これはコンストラクタ");
    }
    public void Object1() {
        System.out.println("これはメソッド");
    }
    public static void main(String[] args) {
        Object1 o = new Object1();
        o.Object1();
    }
}

のソースで、実行結果が

これはコンストラクタ
これはメソッド

となる。


つまり、Object1 クラス中で、

  • public Object1() {...} の宣言だと(クラス名と同名で型指定がないので)コンストラクタ
  • public void Object1() {...} の宣言だと(型指定があるためクラス名と同名にも関わらず)メソッド

という仕様に気持ち悪さが残る、ということですね(public かどうかは今回の話とは無関係です)。

特に触れられてませんが、型指定の無いクラス名と異なるメソッド宣言はコンパイラでエラーになるのは当然、ということでいいですね。


「クラス名と同名で型指定のないメソッド」がコンストラクタとなるのはC++から譲り受けた仕様でしょう。

http://www.bohyoh.com/CandCPP/FAQ/FAQ00084.html


「main メソッドor関数 がvoid」なのは古い(ANSI Cより前の)C言語から譲りうけた仕様でしょう。

http://homepage3.nifty.com/aokura/phoebe/minitips.html#3

http://www.cmagazine.jp/q/old.html#index4


ということで……私では「Java以前の言語から譲り受けているのだろう」という程度の説明しかできません。

C++がコンストラクタを「クラス名と同名で型指定のないメソッド」とした理由はどこかからでてくるかもしれませんが……。すみません。

id:Ryo9508

ありがとうございました。「手続き文」には必ず実行結果=戻り値があるという思い込みは捨てないといけませんね。

2006/04/09 08:17:45
id:kishiro No.4

回答回数161ベストアンサー獲得回数4ここでベストアンサー

ポイント100pt

質問者は、少し誤解されているようです。

http://www.y-adagio.com/public/standards/tr_javalang/index.h...

Java言語では

・コンストラクタ:「必ず型指定しない」

・メソッド:「必ず型指定が必要」

となっており、一貫性があります。

 

型が指定されているコンストラクタは存在しないし

逆に型が指定されていないメソッドも存在しません。

 

「コンストラクタには戻り値がなく,戻り値の型指定をすると一般メソッドとして取り扱われる」

というのは、単に

「クラスやコンストラクタと同じ名称のメソッドを定義できます」

と言い換えることができる。 

 

よって、たまたまクラス、コンストラクタ、メソッドの名称が

全く同じだったとしても、それぞれ異なる役割を果たします。

下記は名称が"Sample"だった場合の例です。

 

public class Sample {

  /** 表示する文言 */

  private String words_;

  /** メインメソッド */

  public static void main(String[] args) {

    //コンストラクタによって、インスタンス初期化

    Sample sample = new Sample();

    //メソッドによって、処理を実行

    sample.Sample();

  }

  /** コンストラクタ */

  public Sample() {

    words_ = "This is Sample !";

  }

  /** メソッド */

  public void Sample() {

    System.out.println(words_);

  }

}

id:Ryo9508

なるほど!確かに誤解をしておりました。メソッドは型指定を省略すればintかvoidになるのかと思っていました(必ず型指定をしていたので気づきませんでした)。型指定が有るか無いかで厳密に違うのですね。

2006/04/09 08:53:11
id:noko-noko No.5

回答回数38ベストアンサー獲得回数3

ポイント30pt

Java 入門 | コンストラクタ


コンストラクタでないメソッドは戻り値を定義しておかないといけません。戻り値がないなら void で。

「必ずvoid指定する」メソッドというよりも、その戻り値を書かないといけないメソッドの中でも、特に public static void main(String[] args) が起動時に呼ばれることになっているだけだと思います。


一方、コンストラクタは戻り値はありませんが、 void を書きません。逆にいうと何も戻り値を書いていないものがコンストラクタです。

コンストラクタは必ずクラスメイト同じ名前になりますが、それとは別に戻り値の void な、クラス名と同じメソッド(コンストラクタでない)を定義できることからも、戻り値を書かないのが、コンストラクタである方がわかりやすいと思います。

id:Ryo9508

ありがとうございました。メソッドは型指定を省略すればintかvoidになるのかと勘違いしていました。

2006/04/09 08:54:56
id:SevenS No.6

回答回数51ベストアンサー獲得回数3

ポイント30pt

重要なのは、プログラマ自身が、一般のメソッドとコンストラクタを分けて考えることだと思います(new+コンストラクタでしか新たなインスタンスを生成できない)。

恐らく、それを促すために、このような言語仕様になっているのではないでしょうか。

mainはそもそもインスタンスがなくても動くメソッドであり、staticである時点でインスタンスとは全く関係がありません。C++でも全く同じことが言えると思います。

余計なことなどと言わず、「オブジェクト指向とはそういうもの」と考えたほうがいいのではないでしょうか。

コンストラクタ

id:Ryo9508

ありがとうございました。

2006/04/09 09:05:51

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません