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

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

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

5回答

4586閲覧

コンストラクタのオーバーロードについて

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/05/21 08:09

編集2017/05/21 14:38

コンストラクタのthis();の動きが理解できないので小さいプログラムでいろいろテストしてみたのですが、いまいち理解ができません。呼び出されるコンストラクタはインスタンスを生成するときの引数の種類と数に応じて自動で判断されているという部分とthis();はコンストラクタに同じ記述をしないで済むというメリットの2点は理解できます。そこで質問です。結果は下です。

  1. 例えばA a = new A(100);でインスタンスを生成したときのプログラムは具体的にどう動いているのでしょうか?結果を見ても考えていた動きと違うので混乱しています。
  2. コンストラクタが複数ある場合this();はどういう基準で別のコンストラクタを呼び出しているのでしょうか?他2つのどちらが呼ばれているのかわかりませんでした。
  3. みなさんはどういう場面でthis();を使おうと考えるのでしょうか?

数時間this();の動きに頭を悩ませています。アドバイスをいただけるとうれしいです。

【追記】
koko_uさんからの追記依頼がありましたので追記いたします。

元々はインスタンスを生成するときに引数を100と指定したのでpublic A(int i)が呼び出されてthis("s");がどういう動きをするのだろうかと勉強のために作ったプログラムでした。

100 s 7

おそらく上記のような表示だろうと考えていたのですが100の表示順どころか3つ目にもsが表示されてしまったところが「考えていた動きと違う」という点です。

Java

1public class A { 2 private String s; 3 private int i; 4 5 public A(String s, int i) { 6 this.s = s; 7 this.i = i; 8 System.out.println(s); 9 System.out.println(i); 10 } 11 12 public A(String s) { 13 this(s, 7); 14 System.out.println(s); 15 } 16 17 public A(int i) { 18 this("s"); 19 System.out.println(i); 20 } 21} 22 23public class Main { 24 public static void main(String[] args) { 25 A a = new A(100); 26 } 27}

Java

1s 27 3s 4100

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koko_u

2017/05/21 13:07

すでにたくさん回答がついてますが、質問者さんの「考えていた動き」がわからないので回答は控えます。
退会済みユーザー

退会済みユーザー

2017/05/21 14:40

「考えていた動き」を追記しました。
guest

回答5

0

ベストアンサー

コンストラクタが複数ある場合this();はどういう基準で別のコンストラクタを呼び出しているのでしょうか?他2つのどちらが呼ばれているのかわかりませんでした。

  1. mainメソッドにおいてnew A(100)

引数がint型1つなので、int型1つを引数にとるpublic A(int i)が呼び出される
0. public A(int i)の1行目においてthis("s")
引数がString型1つなので、String型1つを引数にとるpublic A(String s)が呼び出される
0. public A(String s)の1行目においてthis(s, 7)
sはString型の変数、そして7はint型なので、public A(String s, int i)が呼び出される
0. public A(String s, int i)の処理中、sとiの出力→"s"と"7"が出力される(1行目と2行目)
0. ここでpublic A(String s)の中のthis(s, 7)の処理が終了し、その次の行でsを出力→"s"が出力される(3行目)
0. ここでpublic A(int i)の中のthis("s")の処理が終了し、次の行でiを出力→100が出力される(4行目)

と、これだけの話なのですが…

投稿2017/05/21 13:38

編集2017/05/22 04:20
swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/21 14:26

>public A(String s)の1行目においてthis(s, 7) >sはString型の変数、そして7はint型なので、public A(String s, int i)が呼び出される これですとsと7の2つが表示されて終わりますが実行してみると更にsと100が表示されます。100は引数で指定したので表示される予想はしていたのですが、なぜ3つ目のsが表示されるのかがわかりません。
swordone

2017/05/21 14:42

自クラスのほかのコンストラクタを呼び出しただけで、最初に呼び出したコンストラクタの処理はまだ途中です。メソッド処理中にほかのメソッドを呼び出して、終わったら元の場所に戻って処理を続行するのと全く同じです。
退会済みユーザー

退会済みユーザー

2017/05/22 08:42

おかげさまでメソッドの処理中の動きが少しわかりました。アドバイスありがとうございました!
guest

0

1.についてはHogeAnimalLoverさんが回答されているので・・・

  • コンストラクタが複数ある場合this();はどういう基準で別のコンストラクタを呼び出しているのでしょうか?

コンストラクターでもメソッドでもオーバーロードしているもののどれが選択されるかの規則は同じです。呼び出しの際の実引数の型と個数によってどれになるかが決まります。型は正確に一致してなくても暗黙変換により「一番適合するもの」が選択されます。このあたりは中途半端に考えてもあまり益はないので教科書か言語仕様書で「完全で正確な定義」を参照することをお勧めします。

  • どういう場面でthis();を使おうと考えるのでしょうか?

コンストラクターの引数のバリエーションを持たせたい場合に使います。質問者さんのコードでやっていることと同様ですね。バリエーションを持たせたい理由は「一部の引数を省略したい」ことが多いと思います。残念ながらJavaではデフォルト値を与えることで引数を省略するといったテクニックが言語仕様上サポートされてないため、コンストラクターの引数のバリエーションを作りたいと思ったらオーバーロードするしかありません。しかしオーバーロードした各メソッドの実装を同じように書くのはナンセンスですので、あるコンストラクターは「そのコンストラクターより引数の数が多い別のコンストラクター」を呼び出すようにするのが一般的によく使われるケースだと思います。

投稿2017/05/21 08:44

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/21 14:19

規則は一緒なんですね。少しずつわかってきました。
guest

0

new A(100);
→ public A(int i)
→ this("s") → public A(String s)
→ this(s, 7) → public A(String s, int i)
→ System.out.println(s) ... "s"を出力
→ System.out.println(i) ... 7を出力
→ A(String s) に戻って System.out.println(s) ... "s"を出力
→ A(int i) に戻って System.out.println(i) ... 100を出力

となっているように書かれていますが、どこに疑問を感じますか?

投稿2017/05/21 08:26

SugiTK

総合スコア495

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/21 14:18

→ System.out.println(i) ... 7を出力 → A(String s) に戻って System.out.println(s) ... "s"を出力 int型の引数でインスタンスを生成したのでA(int i)から始まり、そのメソッドのなかの最初の行のthis("s")はString型なので次に・・という行きの流れはわかったのですが、なぜA(String s)に戻るのかがわかりません。
guest

0

A1 public A(String s, int i)
A2 public A(String s)
A3 public A(int i)

と便宜的に記述します。

Mainメソッドの中でA3が呼び出されます。
A3の中
{
→A2が呼び出されます。
→→2の中
→→{
→→→A1が呼び出されます。
→→→→A1の中
→→→→{
→→→→→→→文字列"s"が出力されます。
→→→→→→→数字7が出力されます。
→→→→}
→→→文字列"s"が出力されます。
→→}
→数字100が出力されます。
}

投稿2017/05/21 08:22

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/21 14:23

3つ目がなぜ文字列sなのかがわからないのですが、もしかして→のインデントが関係しているのでしょうか?
guest

0

2に関してですが、引数として受け取れないものは呼び出されません。受け取れる物は次の優先順位になっています。

型が同じ>暗黙的に型変換されるもの>ラッパークラス>可変長引数

例えば、次のコンストラクタがあります。

java

1A (int a) {} // 型が同じ 2A (double a) {} // 暗黙的に型変換されるもの 3A (Integer a) {} // ラッパークラス 4A (String a) {} // A(100)では呼び出されないもの

これらに対してA(100)で呼び出しを行なった場合、A (int a)が呼び出されます。
A (int a)をコメントアウトした場合、A (double a)が呼び出されます。
A (double a)をコメントアウトした場合、A (Integer a)が呼び出されます。
A (Integer a)をコメントアウトした場合、コンパイルエラーになります。
A (String a)の引数はStringであり、100を入れることができないからです。

投稿2017/05/21 08:51

編集2017/05/21 14:21
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/05/21 14:20

優先順位があったんですね。アドバイスありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問