Javaにおける「this」とは変数を区別したり、コンストラクタを呼び出す行う上で欠かせないものですが、初心者だととくに何を示し、なぜ必要なのかを正確に理解している人は少ないものです。
「this」はJavaを学習する中で必ず目にする言葉なので、ぜひとも抑えておきたいところ。今回の記事ではコード例を交えながら「this」の使い方や注意点を解説します。
開発現場でも役立つ知識を、本記事でしっかり身につけましょう。
JAVAのthisとは何?
Javaにおける「this」というのは、現在のオブジェクト自身を表す特殊な変数のことです。変数・メソッドを呼び出すほか、コンストラクタ呼び出しを簡潔に書くなどの用途があります。
たとえば引数名とインスタンス変数名が同じ場合、
のように記述することで区別できたり、また
を使うことで、別のコンストラクタを呼び出せます。
Javaのthisでできることや概要、注意点を一覧にまとめると、以下のとおりです。
変数の区別 | メンバ変数とメソッドの引数やローカル変数が同名の場合、thisをつけることでメンバ変数を指示できる |
コンストラクタの呼び出し | コンストラクタ内から別のものを呼ぶ際に、this()構文を用いて重複コードを整理できる |
メソッド参照 | 同じクラス内のインスタンスメソッド呼び出し時に、thisを利用してメソッドを明示的に参照できる |
staticメンバーとの違い | staticメンバーはクラスに属しているため、インスタンスに紐付くthisを使用できない |
制約・注意点 | コンストラクタ呼び出しのthis()は必ず先頭で記述しなければならない/staticメソッドやクラスメンバーからは使えない |
なお、より初心者向けのJavaプログラミングを学習したい方は、以下の記事をぜひ参考にしてください。
JAVAのthisを使う理由
Javaにおいてthisは、インスタンス変数とローカル変数の区別を明確にするために使用されます。
なぜなら、メソッドの引数やローカル変数は、クラスのフィールド(インスタンス変数)と同じ名前で宣言できるため、どちらを指しているのかが分かりにくくなるからです。この問題を防ぐために、フィールド変数を参照するときはthisを付けるのが一般的というわけです。
たとえば、thisを使用しないで「name」を定義・代入を行う場合、場合、以下のようなコードになります。
public class Sample {
private String name;
public void setName(String name) {
name = name; // ←どちらのnameを指しているかわかりにくい
}
}
上記のコードでは引数「name」がローカル変数として解釈されるので、変数「name」に値が代入されません。
一方、thisを使用する場合は以下のようになります。
public class Sample {
private String name;
public void setName(String name) {
this.name = name; // ←フィールド変数に引数の値を代入
}
}
「this.name = name;」とすることで、「左側は変数、右側は引数」ということが明確になり、意図しているとおりに代入が行われます。
またthisを使うことで読みやすさも向上し、エラーやバグを防ぎやすくなるメリットもあります。
JAVAのthisはどのように使う?
この章では、JAVAのthisのさまざまな使い方を以下のとおりパターン別に解説していきます。
- 変数の区別を行うとき
- コンストラクタの呼び出し
- static変数へのアクセス時
- クラス変数やメソッドの参照時
変数の区別を行うとき
Javaではメソッドの引数やローカル変数、クラスのメンバ変数(またフィールド変数)などが同じ名前になることがあります。こういったときにthisを使うことで、どちらを参照しているのかを明確に区別できます。
たとえば以下のコードにて、メンバ変数とローカル変数の違いをthisを用いて確認してみます。
class ThisExample {
private String message = “Hello, Java!”;
public void displayMessage(String message) {
System.out.println(“message = ” + message); // ここでローカル変数(引数)の値を表示
System.out.println(“this.message = ” + this.message); // ここでメンバ変数の値を表示
}
}
public class Main {
public static void main(String[] args) {
String message = “Hello, World!”;
ThisExample example = new ThisExample();
example.displayMessage(message);
}
}
実行結果:
this.message = Hello, Java!
このコードでは、変数名「message」がメンバ変数とメソッドの引数として重複しています。そこで「this.message」を使用することで区別し、適切な値を参照できます。
コンストラクタの呼び出し
Javaにおけるthisは、別のコンストラクタを呼び出すことにもよく使われています。複数間で共通の初期化処理をまとめられるので、コードの重複を減らせるメリットがあります。
たとえば以下のサンプルコードでは、thisを使用して、1つのコンストラクタから複数を呼び出しています。
private String role;
private String profession;// 引数が1つのコンストラクタ
ThisExample(String profession) {
this(“Warrior”, profession); // 別のコンストラクタを呼び出す
}// 引数が2つのコンストラクタ
ThisExample(String role, String profession) {
this.role = role;
this.profession = profession;
}public void display() {
System.out.println(role);
System.out.println(profession);
}
}public class Main {
public static void main(String[] args) {
String profession = “Engineer”;
ThisExample example = new ThisExample(profession);
example.display();
}
}
Engineer
thisの役割としては「this(“Warrior”, profession);」によって、同じクラス内の別のものを呼び出し、共通の初期化処理をまとめた、といった具合です。
static変数へのアクセス時
Javaのstatic変数(クラス変数)は、インスタンスごとではなくクラス全体で共有される変数です。なので固有の参照を示すthisを使ってアクセスすると、書き方が不適切という旨の警告が出る可能性があります。
static変数にアクセスする際は、以下のコードのように「this.変数名」ではなく、「クラス名.変数名」の形式で記述することが推奨されます。
static String message;
public void setMessage(String message) {
this.message = message; // ←このようにthisを使うと警告が出る
StaticExample.message = message; // ←このようにクラス名を指定すると適切
}public void displayMessage() {
System.out.println(StaticExample.message);
}}public class Main {
public static void main(String[] args) {
StaticExample example = new StaticExample();
example.setMessage(“Hello, Java!”);
example.displayMessage();
}
}
上記にあるとおり「this.message = message;」のように書くと、警告が発生する可能性があります。thisは主にインスタンスを指すため、クラス全体で管理されるstatic変数に対して適切ではありません。
StaticExample.message = message; と記述することで、正しくstatic変数にアクセスできます。
クラス変数やメソッドの参照時
Javaでクラスを継承し場合、サブクラスはスーパークラスのメンバ変数やメソッドを引き継ぎます。
このとき、サブクラス内にスーパークラスと同じ名前の変数やメソッドがある場合、どちらを参照しているのかが曖昧になってしまいます。
そこでthisを使うことでサブクラスのメンバを、また「super」を使うことでスーパークラスのメンバを明確に区別できます。
String message = “SuperClass”;
public String getMessage() {
return message;
}}
class SubClass extends SuperClass {
String message = “SubClass”;public String getMessage() {
return message;
}public void display() {
System.out.println(“super.message = ” + super.message);
System.out.println(“this.message = ” + this.message);
System.out.println(“message = ” + message);
System.out.println(“super.getMessage() = ” + super.getMessage());
System.out.println(“this.getMessage() = ” + this.getMessage());
System.out.println(“getMessage() = ” + getMessage());
}
}public class Main {
public static void main(String[] args) {
SubClass obj = new SubClass();
obj.display();
}
}
実行結果:
this.message = SubClass
message = SubClass
super.getMessage() = SuperClass
this.getMessage() = SubClass
getMessage() = SubClass
上記を解説すると、
- super.message はスーパークラスの message (“SuperClass”) を参照
- this.message はサブクラスの message (“SubClass”) を参照
- super.getMessage() はスーパークラスの getMessage() を実行、”SuperClass” を返している
- this.getMessage() または getMessage() はサブクラスの getMessage() を実行、”SubClass” を返している
といった形です。
このような形で「super」と「this」を上手に活用することで、スーパークラスとサブクラスの変数・メソッドを適切に使い分けることが可能になります。
また以下では、Javaのif文についてくわしく解説しています。if文はすべてのプログラミングで必ず使われる言語なので、ぜひ把握しておくことをおすすめします。
JAVAのthisが使えないケース
thisはインスタンス自身を指すため、インスタンスが存在しないstaticなコンテキストでは使用できません。
staticメソッドやstaticブロック、staticな内部クラス内でthisを使用してみるとコンパイルエラーになります。なぜならstaticメンバーはクラスに属し、特定のインスタンスに紐づかないため、thisの対象が特定できないからです。
以下のサンプルコードで確認してみましょう。
int instanceVar = 10;
static int staticVar;// コンパイルエラー(staticな文脈ではthisは使えない)
// static int errorVar = this.instanceVar * 10;
static {
// System.out.println(this);
// コンパイルエラー
}public static void staticMethod() {
// System.out.println(this); // コンパイルエラー
}// 正しいstatic変数を使用した例
public static void setStaticVar(int value) {
staticVar = value; // thisは不要
}
}
thisはクラススコープ、staticブロック、staticメソッドでは使用できません。「staticVar = value;」のように。thisを使わずにアクセスする必要があります。
thisはインスタンスのコンテキストでのみ有効ということを覚えておきましょう。
JAVAのthisを使う際の注意点
thisの注意点としては、前述した「使えないケース」を含め以下のようなものがあります。
- 別のコンストラクタを呼び出す場合、コンストラクタの最初にthisを記述する
- thisはあまりに多用すると逆に冗長なコードになってしまう
まず別コンストラクタを呼ぶ場合は、以下のように最初にthisを入力しなければならない点に注意してください。
private int value;
private String text;
public Example(int value) {
this(value, “default”); // ←正しい使用法
}public Example(int value, String text) {
this.value = value;
this.text = text;
}
}
public class Employee {
private String name;
public void setName(String newName) {
name = newName; // ←こういった場合thisは不要
}
}
初心者からJAVAを学習する方法
初心者からJAVAを学習する方法には、主に以下があります。
- 書籍で独学を行う
- 動画サイトを駆使して学ぶ
- ITセミナーやスクールを活用する
それぞれ見ていきましょう。
学習法①書籍で独学を行う
書籍を用いて独学する方法です。JAVAは非常に高需要で人気の言語のため、書店やネットにもさまざまな書籍があります。
誰からも急かされることなく自分のペースでじっくり進められ、かつ自力で苦労しながら解決にこぎつけるため、知識が身につきやすいです。
ただ時間がかかること、そして挫折の可能性が高いことがデメリットです。
学習法②動画サイトを駆使して学ぶ
インターネットの情報よりも、動画形式のものを活用して体系的に学ぶこともおすすめです。動画歯画像と文字のコンテンツと比較して圧倒的に情報量が多く、申し分ないインプットが可能になるからです。
こちらも誰からも急かされず自分のペースで、かつお金もかけずに学習できるのがメリットですが、アウトプットが不足しやすいこと、挫折率が高いことがデメリットです。
学習法③ITセミナーやスクールを活用する
もっとも効率の良い学習方法として挙げられるのが、ITセミナーやスクールの活用です。専門知識をもつ方からわからない部分を手取り足取り教えてもらえるため、良質なインプットとアウトプットが実現できます。
また同じ志をもつ方との切磋琢磨があること、そして決して安くはないお金がかかるのでモチベーションも維持しやすいです。ただ自分のペースで学習を進めたい方には不向きです。
JAVAのthisまとめ
ここまでJavaのthisについて、概要から具体的な使い方、使えないケースや注意点までを見てきました。コンストラクタ呼び出しや変数の区別など、状況に応じてthisを活用すればコードの可読性や保守性が向上します。
一方でstaticメソッド内では使えないなどの制約もあるため、誤った使い方をしないためにも知識をつけておくことが大切です。今後の開発では、thisを意識的に使いこなし、より分かりやすく効率的なプログラムを目指しましょう。
