Javaのthisキーワードとは?使い方を初心者向けにわかりやすく解説
Javaのthisキーワードの使い方
Javaでコーディングを始めると、メソッドやコンストラクタ内でthisキーワードが使われていることに気づくでしょう。thisキーワードは、メソッドやコンストラクタ内における「現在のオブジェクト」を参照するもので、Javaプログラミングにおいて幅広い用途を持っています。
このチュートリアルでは、Javaのthisキーワードについて、その使い方と使用する理由を詳しく解説します。記事全体を通して、thisキーワードが実際にどのように動作するのかを示すサンプルコードも多数紹介します。
Javaのメソッドとコンストラクタの基礎
メソッドとコンストラクタは、Javaプログラミングにおける2つの重要な要素です。
オブジェクト指向プログラミングで「メソッド」と呼ばれる関数は、特定のタスクを実行するコードのブロックです。例えば、メソッドを実行すると、配列の内容をコンソールに出力したり、プログラム内でユーザー入力を処理したりできます。
以下は、It's Monday!をコンソールに出力するJavaのメソッドの例です。
public class PrintMessage {
public static void main(String[] args) {
System.out.println("It's Monday!");
}
}
このコードを実行すると、コンソールに次の出力が返されます。It's Monday!
コンストラクタはメソッドに似ていますが、プログラム内でオブジェクトがインスタンス化(生成)されるときに自動的に呼び出される点が異なります。以下は、Mondayクラスのインスタンスが生成されるときに、dayというインスタンス変数の値をMondayに設定し、It'sに続いて曜日をコンソールに出力するコンストラクタの例です。
class Monday {
private Monday() {
day = "Monday";
}
public static void main(String[] args) {
Monday day_of_the_week = new Monday();
System.out.println("It's " + day_of_the_week.day);
}
}
このコードの実行結果は次のとおりです。It's Monday!
コンストラクタについてさらに詳しく知りたい方は、Javaコンストラクタの専用ガイドも併せてご覧ください。Javaのメソッドとコンストラクタの基本を押さえたところで、いよいよthisキーワードの本体と、コードでの具体的な使い方を見ていきましょう。
Javaのthisキーワードの正体
Javaにおいて、thisキーワードはメソッドやコンストラクタ内の「現在のオブジェクト」を参照します。
これを実際に確認するために、先ほどの曜日をコンソールに出力するコンストラクタの例を使ってみましょう。以下の例では、thisの値と、インスタンス化したMonday()オブジェクトの値をそれぞれ出力しています。
class Monday {
private String day;
private Monday() {
day = "Monday";
System.out.println(this);
}
public static void main(String[] args) {
Monday day_of_the_week = new Monday();
System.out.println("It's " + day_of_the_week.day);
System.out.println(day_of_the_week);
}
}
このコードは以下の結果を返します。
Main@d716361 It's Monday Main@d716361
出力の1行目はthisの値で、Monday()オブジェクトがインスタンス化された時点でコンソールに出力されています。2行目は、It'sに続けて、宣言したday_of_the_weekオブジェクトのdayフィールドの値を出力した結果です。最後の行では、day_of_the_weekオブジェクト自体の値を出力しています。
ご覧のとおり、thisの値とday_of_the_weekオブジェクトの値は完全に一致しています。つまり、thisキーワードは、メソッドやコンストラクタ内の現在のオブジェクトを参照しているということが確認できます。
Javaのthisキーワードの2つの主な使用例
thisキーワードの使用が特に有効な場面は、主に次の2つです。
- 変数名の曖昧さを解消するためにthisを使う
- 引数としてthisを渡す
なお、thisキーワードの亜種であるthis()は、コンストラクタのオーバーロードでも使用されます。ただしこれはやや高度なテクニックなので、この記事では割愛します。
変数名の曖昧さを解消するためにthisを使う
Javaでは、同じスコープ内に同じ名前の変数を複数宣言することはできません。そのため、同じ名前の変数を宣言して使おうとすると、プログラムのロジックに不具合が生じます。
しかし、thisを使えばこの制限を回避できます。thisを利用すると、特定の変数をオブジェクトのフィールドとして明示的に割り当てられるため、パラメータの値とインスタンス変数の値を区別して扱えるようになります。
この仕組みを理解するために、具体的な例を見てみましょう。5年生のクラスで、優等生リスト(honor roll)に追加される生徒の名前を管理するプログラムを作成するとします。このアプリケーションは、生徒の名前をコンソールに出力する必要があります。
このアプリケーションを作成するコードは以下のとおりです。
class HonorRoll {
String studentName;
HonorRoll(String studentName) {
this.studentName = studentName;
}
public static void main(String[] args) {
HonorRoll alex = new HonorRoll("Alex");
System.out.println("New honor roll inductee: " + alex.studentName);
}
}
プログラムを実行すると、次の結果が返されます。
New honor roll inductee: Alex
この例では、HonorRollコンストラクタ内で生徒の名前を正しく保存するためにthisを使用しています。次のコード行により、コンストラクタパラメータstudentNameの値(上の例ではAlex)が、インスタンス変数this.studentNameに代入されます。
もしthisを付けずにstudentName = studentName;と書いた場合、次のような結果になってしまいます。
New honor roll inductee: null
これは、パラメータとフィールドが同じ名前だと、Javaコンパイラがどちらを指しているのか判断できず、代入が正しく行われないためです。つまり、thisを外してしまうと、フィールドには何も代入されずnull値が返されることになります。
引数としてthisを渡す
thisキーワードは、メソッドやコンストラクタ内の現在のオブジェクトを、別のメソッドに渡すためにもよく使われます。
例えば、地元のコーヒーショップが在庫として保有しているコーヒー豆の袋数を管理するアプリケーションを作成するとします。このアプリケーションでは、オーナーが新しい在庫を入荷したときに、既存の在庫総数に追加できるようにします。このアプリケーションを実現するコードは以下のとおりです。
class AddStock {
int stockToAdd;
int stockTotal;
AddStock(int stockToAdd, int stockTotal) {
this.stockToAdd = stockToAdd;
this.stockTotal = stockTotal;
System.out.println("Current stock: " + this.stockTotal);
calculateNewStock(this);
System.out.println("New stock: " + this.stockTotal);
}
void calculateNewStock(AddStock s) {
s.stockTotal += s.stockToAdd;
}
}
class Main {
public static void main(String[] args) {
AddStock newStockValue = new AddStock(10, 9);
}
}
このコードは以下の結果を返します。
Current stock: 9 New stock: 19
コードを分解して見ていきましょう。このコードでは、AddStockというクラスを定義しています。このクラスのコンストラクタは、2つの値(stockToAddとstockTotal)を受け取り、calculateNewStock()メソッドを呼び出して、コーヒーショップの在庫数を計算します。
続いて、Main()クラスでAddStockクラスのインスタンスを初期化し、10と9という2つの値を渡しています。プログラムが実行されると、指定された2つの値(追加する在庫数と現在の在庫総数)が加算され、現在の在庫数と更新後の在庫数の両方がコンソールに出力されます。
この例のポイントは、calculateNewStock()メソッドを呼び出す際に、thisキーワードが引数として使われている点です。これにより、AddStockクラス内で扱っている現在のオブジェクト(とそのフィールド)を、在庫計算のためにそれらの値を必要とするcalculateNewStock()メソッドにそのまま渡すことができます。
まとめ
Javaのthisキーワードは、メソッドやコンストラクタ内の現在のオブジェクトを参照するものです。Javaにおけるthisキーワードには、主に2つの用途があります。1つ目は変数名の曖昧さを解消すること、2つ目は引数として現在のオブジェクトを渡すことです。
このチュートリアルでは、具体的なコード例を交えながら、これらの場面でJavaのthisキーワードをどのように活用するかを解説しました。これで、あなたもthisキーワードをエキスパートのように使いこなすための知識を身につけたはずです。
-
Java Swingはスレッドセーフではない?その理由とEDTの正しい使い方を解説
結論から言うと、Java Swingのコンポーネントはスレッドセーフではありません。複数のスレッドから同時にSwingコンポーネントへアクセスすると、描画の不整合やデッドロックなど予期しない動作を引き起こす可能性があります。Swingがスレッドセーフではない理由最大の理由は、コンポーネントの拡張(サブクラス化)を簡単にするためです。すべてのメソッドで同期処理を行うと、開発者がオーバーライドして独自のコンポーネントを作る際に、ロックの扱いまで意識する必要が生じ、設計が複雑になってしまいます。もう一つの理由は、ロックの取得・解放や状態の復元にかかるオーバーヘッドです。全メソッドをスレッドセーフにす
-
Javaで「this」に新しい参照を代入することは可能ですか?
Javaにおける「this」キーワードは、インスタンスメソッドやコンストラクタの中で現在のオブジェクトを参照するために使われる特別なキーワードです。これを利用することで、クラスのメンバーであるコンストラクタ、フィールド(変数)、メソッドなどを参照することができます。 「this」への参照の代入は可能か? 定義によれば、「this」はキーワードであり、現在のオブジェクト(そのコンストラクタやメソッドを実行中のオブジェクト)への参照として機能します。その値は固定されており、変更することはできません。つまり、「this」に新しい参照値を代入することはできません。 そもそも「this」は単なるキーワ