広告

手を動かして学ぶ Java入門 (thisキーワード)

環境構築不要! ブラウザから直接コードを実行できます。
本記事では、クラスで使う this キーワードについて学びます。

15分くらいで、さくっと終わる記事をめざしています。


シリーズ一覧

続きは近日公開予定!

はじめに

この記事は paiza.IO の「Online Java compiler」を利用しています。
2024/12/23 現在、上記環境の Java バージョンは 18 です。(paiza.IO利用ガイド)

実行したコードは paiza.IO で保存および公開されることがあります。
そのため、個人情報などの機密性の高い情報は、コードとして入力しないようにご注意ください。

詳細は paiza.IO の利用規約およびプライバシーポリシーをご確認ください。

this キーワード

this キーワードとは、簡単にいうと…

  • クラス自身のインスタンスが格納された変数

のことです。

例えば、次のような Sample クラスがあるとしましょう。

public class Sample {
    public void test(Sample sample) {
        System.out.print(this == sample);
    }
}

Sample クラスの test メソッドは、Sample クラスのインスタンスをパラメータとして受け取ります。

public void test(Sample sample) {
                 ^^^^^^^^^^^^^^ <--- Sample クラスのインスタンスを受け取る
    ...
}

そして、それを this と比較します。

public void test(Sample sample) {
    System.out.print(this == sample);
                     ^^^^^^^^^^^^^^ <--- this と比較!
}

もし、thissample パラメータが同じであれば、

true

と出力されるはずです。

実際にプログラムを動かして確認してみましょう。
コードは変更せずに、そのまま「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

true
false
true

と表示されたら成功です。


例えば、

sample1.test(sample1);

というコードは、変数の sample1 とその this が同じものになります。

つまり、

public void test(Sample sample) {
    System.out.println(this == sample);
}

↑の出力が true となるわけですね。


sample2.test(sample2);

このコードも同様です。
sample2 とその this は同じです。


sample1.test(sample2);

こちらは、sample1this は、sample2 とは違うものです。
よって、出力は false となります。

this キーワードがどのようなものか、なんとなくイメージできましたでしょうか…?
ただ、なんのために使うんだろう … と疑問に思うかもしれません。

それでは、this キーワードの利用例を見ていきましょう。

フィールドへのアクセス

比較のために、まずは this キーワードを使わない例を見てみます。

public class Sample {
    private int value;

    public void set(int v) {
        value = v;
    }

    public void print() {
        System.out.println("値 : " + value);
    }
}

Sample クラスは value という名前のフィールドを宣言しています。

public class Sample {
    private int value;
                ^^^^^ <--- クラスフィールド!
    ...
}

そして、set メソッドで、value フィールドに値を代入します。

public class Sample {
    ...

    public void set(int v) {
        value = v;
        ^^^^^ <--- クラスフィールドへ代入!
    }

    ...
}

最後に、print メソッドで value フィールドを出力します。

public class Sample {
    ...

    public void print() {
        System.out.println("値 : " + value);
                                     ^^^^^ <--- クラスフィールドを出力!
    }
}

実際にプログラムを動かして確認してみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

値 : 0
値 : 999

と表示されたら成功です。

ここまでは前回までの復習ですね。

さて、先ほどの Sample クラスですが、set メソッドのパラメータ名を value にしたいとしましょう。

public class Sample {
    private int value = 1;

    public void set(int value) {
                        ^^^^^ <--- この部分
        value = value;
    }

    ...
}

プログラミングをしていると、

  • メソッドのパラメータ名に、フィールド名と 同じ名前 を使いたい

ということが結構あります。
わざわざ別の名前を考えるのも面倒ですしね…

今までは苦肉の策として、メソッドのパラメータ名とフィールド名を別にしていました。

public void set(int v) {
                    ^ <--- メソッドのパラメータ名
    value = v;
    ^^^^^ <--- フィールド名
}

ただ、本当は次のようにしたいのです。

public void set(int value) {
    ...

しかし、単純にメソッドのパラメータ名を value にすると、なんだかおかしなことになりそうです…

public void set(int value) {
    value = value;
    ^^^^^^^^^^^^^ <--- ???
}

実は、この書き方はコンパイルエラーにはなりません。
ただし、期待した動作にはなりません。

実際にプログラムを動かして確認してみましょう。
結果がどうなるか予想してから「実行(Ctrl-Enter)」ボタンを押してください。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

値 : 0
値 : 0

と表示されたら成功です。

エラーにはなりませんでしたね。
しかし、クラスフィールドの value に値は代入されませんでした。

Java では、ローカル変数とクラス・フィールド名が同じ場合…

  • ローカル変数を優先する

という仕様があります。
(メソッドのパラメータもローカル変数の1つです)

よって、

public void set(int value) {
                    ^^^^^ <--- 変数1
    value = value;
            ^^^^^ <--- 変数2
    ^^^^^ <--- 変数3
}

上記の変数1、変数2、変数3は、どれも 同じ変数 になります。
つまり、同じ変数に対して同じ変数を代入しているだけですね。

この問題を解決するために、this キーワードを使います。
this キーワードを使うことで、クラスフィールドにアクセスすることを 明示 できます。

public void set(int value) {
    this.value = value;
    ^^^^^^^^^^ <--- クラスフィールドへ代入!
}
  • this + ドット(.) + クラスフィールド

という書き方が基本となります。

それでは、先ほどのコードを書き換えて、期待どおりの動作になるか試してみましょう。

public class Sample {
    private int value;

    public void set(int value) {
        value = value;
        ^^^^^ <--- ★この部分を…
    }
...
}
public class Sample {
    private int value;

    public void set(int value) {
        this.value = value;
        ^^^^^^^^^^ <--- ★このように修正してください。
    }
...
}

Sample クラスの set メソッドに this キーワードを書き加えてから「実行(Ctrl-Enter)」してみましょう。

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

いかがでしたでしょうか? 「出力」のところに

値 : 0
値 : 999

と表示されたら成功です。

無事、期待どおりになりました。

メソッドへのアクセス

this キーワードで自身のクラスメソッドへアクセスもできます。
ただし、あまり必要になることはありません。

そんなこともできるんだ … と頭の片隅にでも置いておけば十分かな、と思います。

【コード例】

public class Sample {

    private int count;

    public void increment() {
        count++;

        this.print();
        ^^^^^ <--- ★この部分
    }

    private void print() {
        System.out.println("count = " + count);
    }
}
Sample sample = new Sample();
sample.increment();
sample.increment();

【結果】

count = 1
count = 2

応用問題

【問題】

まずは、下記のプログラムをそのまま「実行(Ctrl-Enter)」してみましょう。
結果として次のように「出力」に表示されたはずです。

value1 = 0
value2 = 0

そこで問題です。

Sample クラスに this キーワードを書き加えて、プログラムを実行すると、

value1 = 20
value2 = 50

と「出力」に表示されようにしてください。

それでは、Sample クラスに "this." を書き加えてから「実行(Ctrl-Enter)」してみましょう。
(修正するのは Sample クラスだけです)

注意:コードは2ファイルあります。上部のタブで切り替え可能です。

タブ

(表示がおかしいときは「コードの再読み込み」ボタンを押してみてください)

無事に、

value1 = 20
value2 = 50

と出力されましたでしょうか?

もし解けなかった場合は、下記の回答例をご参照ください。

回答例

【コード】

public class Sample {

    private int value1;
    private int value2;

    public void set(int value1, int value2) {
        this.value1 = value1 * 2;
        this.value2 = this.value1 + value1 + value2;
    }

    public void print() {
        System.out.println("value1 = " + value1);
        System.out.println("value2 = " + value2);
    }
}

※ Main.java は書き換えません。

【出力】

value1 = 20
value2 = 50

まとめ

this キーワードとは、

  • クラス自身のインスタンスが格納された変数

のことです。
メソッドのパラメータ名に、クラスのフィールド名と 同じ名前 を使いたいときに便利です。

ぜひ有効に活用していきたいですね。

それでは次回もお楽しみに!


関連記事

ページの先頭へ