thisフィールド
クラスには「thisフィールド」という、作らなくても最初から存在するフィールドがあります。
このthisフィールドを使ってみましょう。
/**
* メソッドとフィールドを持つクラス。
* 「println( data )」が「println( this.data )」になった
* 点以外はHasMethodAndFieldRunnerクラスと同じです。
*/
class UseThisField
{
// int型変数のフィールドです。
int data;
/**
* dataフィールドを出力するメソッドです。
*/
void printData()
{
// thisフィールド経由でdataフィールドを使用します。
System.out.println( this.data );
}
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class UseThisFieldRunner
{
public static void main( String[] args )
{
// UseThisFieldクラスの参照型変数とインスタンスを作ります。
UseThisField ref = new UseThisField();
// dataフィールドに数値を入れます。
ref.data = 100;
// printData()メソッドを呼び出します。
ref.printData();
// 出力結果:
// 100
}
}
// UseThisField.java /** * メソッドとフィールドを持つクラス。 * 「println( data )」が「println( this.data )」になった * 点以外はHasMethodAndFieldRunnerクラスと同じです。 */ class UseThisField { // int型変数のフィールドです。 int data; /** * dataフィールドを出力するメソッドです。 */ void printData() { // thisフィールド経由でdataフィールドを使用します。 System.out.println( this.data ); } } /** * 実行用クラス。このクラスを実行してください。 */ class UseThisFieldRunner { public static void main( String[] args ) { // UseThisFieldクラスの参照型変数とインスタンスを作ります。 UseThisField ref = new UseThisField(); // dataフィールドに数値を入れます。 ref.data = 100; // printData()メソッドを呼び出します。 ref.printData(); // 出力結果: // 100 } }
このプログラムのUseThisFieldクラスは、前ページのHasMethodAndFieldクラスとほとんど同じです。
HasMethodAndFieldクラスとの違いは、dataフィールドを、thisフィールドを経由して使用しているという点です。
System.out.println( this.data );
// thisフィールド経由でdataフィールドを使用します。 System.out.println( this.data );
thisフィールドは何もしなくても自動的に作られるという特殊なフィールドです。
dataフィールドは「int data;」という形で作っていましたが、thisフィールドはそんなことしなくても使うことができます。
では、thisフィールドはどんな型で何が入っているんでしょうか。
まず型は自クラスの参照型です。この例では、UseThisFieldクラスの中で使っているのでthisフィールドの型はUseThisFieldクラスの参照型です。また、HasMethodクラス内ではHasMethodクラスの参照型ですし、HasMethodAndFieldクラス内ではHasMethodAndFieldクラスの参照型になります。
では値はというと、それは自インスタンスの参照です。
次のプログラムのようにインスタンスを作成したときに得られる参照が、thisフィールドに入れられるのです。
UseThisField ref = new UseThisField();
// UseThisFieldクラスの参照型変数とインスタンスを作ります。 UseThisField ref = new UseThisField();
インスタンスを作るとその参照が返されますが、同時にインスタンス内にthisフィールドが作られ、その中にも参照がコピーされます。
thisフィールドには自インスタンスの参照が入るので、ref変数とthisフィールドの両方が1つのインスタンスの参照を持っていることになります(もっとも、クラスの外からthisフィールドを使うことはできないのであまり関係ありませんが)。
また、自インスタンスの参照が入っているということは、当然thisフィールドの型は自クラスの参照型ということになるわけです。
このthisフィールドは自インスタンスへの参照を持っていますから、この参照を通してフィールドを使うことができます。
* dataフィールドを出力するメソッドです。
*/
void printData()
{
// thisフィールド経由でdataフィールドを使用します。
System.out.println( this.data );
}
/** * dataフィールドを出力するメソッドです。 */ void printData() { // thisフィールド経由でdataフィールドを使用します。 System.out.println( this.data ); }
つまり、「this.data」は「ref.data」と同じということです。
thisフィールドで自インスタンスを参照しなおして、改めてdataフィールドを使用しているわけです。
と言っても、メソッド内では何も付けなくても自インスタンスのフィールドを使うことができるので、別に「this.」を付けても付けなくても変わりません。
つまり、
System.out.println( this.data );
も、
System.out.println( data );
も同じということです。
となると「なんでthisフィールドなんてあるの?」と思うかもしれません。
使い道としては、たとえば「フィールドと通常の変数の名前が同じ」という場合にフィールドであることを明示する時に使用したり、メソッドの戻り値として自インスタンスの参照を返す必要がある場合に「return this;」としたりといったことに使います。