LoginSignup
1
0

More than 1 year has passed since last update.

【Java】コンストラクタにおけるthis

Last updated at Posted at 2022-08-15

はじめに

コンストラクタにおけるthisの挙動が頭の中でごっちゃになっていたので学習しました。
アウトプットを兼ねて記事投稿したいと思います。

いきなり結論

thisの役割:「自クラスの別のコンストラクタを呼び出す

実行環境

OS:Windows10 バージョン20H2
言語:Java 8
使用ツール:Spring Tool Suite 4

1. コンストラクタのthisの使い方・動作

⑴ 使い方

自クラスの別のコンストラクタを呼び出したい場合、このように記述します。
this(引数);
もちろん引数なしでも可能です。

⑵ 動作

Main.java
Public class Main {
	public static void main(String[] args) {
		new Test("world!!");
	}
}

class Test{
	public Test() {
		System.out.println("Hello");
	}	
	public Test(String val) {
		this();
		System.out.println(val);
	}
}

上記コードではTestクラスのコンストラクタ(引数あり・引数なし)を2つ用意し、Mainクラス内でnewして引数に文字列「world!!」を記述しています。

すると、実行結果は下記の通りになります。

Hello
world!!

この場合、生成されたTestインスタンスにString型の引数があるため、引数ありのTestコンストラクタが起動します。

すると別のコンストラクタを呼び出すthisが最初に記述されているため、引数なしのコンストラクタが呼び出され、上記の実行結果が表示されます。

もちろん逆もできます。

Main.java
public class Main {
	public static void main(String[] args) {
		new Test();
	}
}

class Test{
	public Test() {
		this("Hello");
		System.out.println("world!!");
	}
	public Test(String val) {
		System.out.println(val);
	}
}
Hello
world!!

上記コードでは、生成されたTestインスタンスに引数が無いため、引数なしのTestコンストラクタが起動します。

先程とは逆に引数ありの別のコンストラクタが呼び出され、上記の実行結果が表示されます。

2. 注意点

⑴ コンストラクタの先頭に置けない

Main.java
public class Main {
	public static void main(String[] args) {
		new Test();
	}
}
class Test{
	public Test() {
		System.out.println("これは");
		this("エラーだ!");
	}
	
	public Test(String val) {
		System.out.println(val);
	}
}
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Constructor call must be the first statement in a constructor

Javaの仕様上、thisはコンストラクタ内の先頭にしか置けません。
先頭以外に記述した場合、上記の実行結果のように怒られます。

⑵ superとthisを同じコンストラクタ内で使用できない

コンストラクタにおけるsuperも、thisと同様にコンストラクタ内の先頭にしか置けません。
そのため、superとthisを1つのコンストラクタ内で併用することは不可能です。

3. でもthisとsuperの2つを使いたいときあるじゃん!

仰る通りです。
1つのクラス内であれば可能です。

Main.java
public class Main {
	public static void main(String[] args) {
		new Test();
	}
}

class SuperTest{
	public SuperTest() {
		System.out.println("親!");
	}
}

class Test extends SuperTest{
	public Test() {
		this("Hello!!"); 
		System.out.println("world!!");
	}
	
	public Test(String val) {
		super();
		System.out.println(val);
	}
}
親!
Hello!!
world!!

チョット複雑ですが、以下のような処理が行われています。


⓵ 引数なしのTestインスタンスが生成されて、引数なしのコンストラクタ、public Test()を呼び出す。

⓶ 他のコンストラクタを呼び出すthis("Hello!!")が起動し、引数ありのコンストラクタ、public Test(String val)が呼び出される。

⓷ 親クラスのコンストラクタを呼び出すsuper()によって親クラスの引数なしコンストラクタ、SuperTest()にアクセスし、「親!」を表示する。

super()の処理が終わったため、今度は引数ありのコンストラクタ、Test(String val)Test()内のthis("Hello!!")で受け取った文字列「Hello!!」を表示する。

this("Hello!!")の処理が終わったため、Test()にて文字列「world!!」を表示する。


上記のような動作が行われるため、別々のコンストラクタであれば、superとthisを1つのクラス内で使用することが可能です。

参考資料

【参考記事】

【参考書籍】
徹底攻略 Java SE 11 Silver 問題集[1Z0-815]対応

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0