Javaキーワードthisの詳細

20811 ワード

Java全体では,コード開発であればほとんどthisから離れられない.Javaでは、このクラスのプロパティ、クラスのメソッド、現在のオブジェクトを表す3つのことができます.
一、「this.属性」はこの類の属性を表す
説明する前に、コードを見てみましょう.
package com.wz.thisdemo;

class Person {
    private String name ;
    private int age ;
    public Person(String n,int a) {
              name = n ;
              age = a ;
    }        
    // setter、getter 
    public String getInfo() {
              return "  :" + name + ",  :" + age ;
    }
}

public class TestDemo {
    public static void main(String args[]) {
              Person per = new Person("  ",20) ;
              System.out.println(per.getInfo()) ;
    }
}

実行結果:
  :  ,  :20

構造方法を観察してみましょう.
    public Person(String n,int a) {
              name = n ;
              age = a ;
    }  

このときの構造方法の2つのパラメータの目的はクラスのnameとageの2つの属性を初期化することですが、この方法の2つのパラメータは、1つはアルファベットnで、もう1つはアルファベットaです.どういう意味ですか.最良の方法は、構築方法の2つのパラメータがnameとage属性の初期化のために使用される以上、その名前もnameとageとして定義するのが最も適切である.
    public Person(String name,int age) {
              name = name ;
              age = age ;
    } 

このとき,構造方法上の2つのパラメータの名前が有意義になる.しかしこれにより,一つの問題が発生し,属性に内容がないことが分かった.プログラムの中では「{}」を1つの境界として近くの取用原則を採用しているので,今では操作するクラスの属性を明確に指定できるようにするには,「this.属性」の形式で完成すべきであり,コードは:
    public Person(String name,int age) {
              this.name = name ;
              this.age = age ;
    }

1つの開発提案:このクラスのプロパティを呼び出す場合は、「this.プロパティ」を使用します.
二、thisはこのクラスのメソッドを呼び出します
1つのクラスのメソッドは2つに分けられます:(1)一般的なメソッド:今呼び出すのがこのクラスのメソッドであれば、「this.メソッド()」を使用して呼び出すことができます.(2)コンストラクションメソッド:コンストラクションメソッドを呼び出すには「this(パラメータ...)」を使用します.
たとえば、1つのクラスに3つのコンストラクションメソッド(パラメータなし、パラメータ1、パラメータ2)が存在しますが、どのコンストラクションメソッドを使用しても、インスタンス化オブジェクトが生成されたときに「新しいクラスオブジェクトがインスタンス化された」というプロンプトを出力する必要があります.以前の学習に従って、コードは以下のように記述されています.
package com.wz.thisdemo;

class Person {
    private String name ;
    private int age ;
    public Person() {
              System.out.println("***     Person       。") ;
    }
    public Person(String name) {
             System.out.println("***     Person       。") ;
              this.name = name ;
    }
    public Person(String name,int age) {
             System.out.println("***     Person       。") ;
              this.name = name ;
              this.age = age ;
    }       // setter、getter 
    public String getInfo() {
              return "  :" + this.name + ",  :" + this.age ;
    }
}
public class TestDemo {
    public static void main(String args[]) {
              Person per = new Person("  ",20) ;
              System.out.println(per.getInfo()) ;
    }
}

実行結果:
***     Person       。
  :  ,  :20

しかし、残念なことに、この時のプログラムには大量の重複コードが現れ、私たちの目標はできるだけ重複しないことです.この場合、this()を使用して完了できます.
package com.wz.thisdemo;

class Person {
    private String name ;
    private int age ;
    public Person() {
              System.out.println("***     Person       。") ;
    }
    public Person(String name) {
              this() ;       //       
              this.name = name ;
    }
    public Person(String name,int age) {
             this(name) ;       //           
              this.age = age ;
    }       // setter、getter 
    public String getInfo() {
              return "  :" + this.name + ",  :" + this.age ;
    }
}
public class TestDemo {
    public static void main(String args[]) {
              Person per = new Person("  ",20) ;
              System.out.println(per.getInfo()) ;
    }
}

実行結果:
***     Person       。
  :  ,  :20

以上this()を用いて,構造方法間の相互呼び出し操作を完了した.
ただし、すべてのコンストラクションメソッドは、オブジェクトがインスタンス化されたときにデフォルトで呼び出され、通常のメソッドが呼び出される前に呼び出されるため、「this()」を使用してコンストラクションメソッドを呼び出す操作は、コンストラクションメソッドの最初の行に必ず配置されます.
    public Person(String name) {
              this() ;       //       ,    
              this.name = name ;
    }

また、コードを見てみましょう.
package com.wz.thisdemo;
class Person {
    private String name ;
    private int age ;
    public Person() {
              this("",10) ;       //          
              System.out.println("***     Person       。") ;
    }
    public Person(String name) {
              this() ;       //          
              this.name = name ;
    }
    public Person(String name,int age) {
              this(name) ;       //           
              this.age = age ;
    }       // setter、getter 
    public String getInfo() {
              return "  :" + this.name + ",  :" + this.age ;
    }
}
public class TestDemo {
    public static void main(String args[]) {
              Person per = new Person("  ",20) ;
              System.out.println(per.getInfo()) ;
    }
}

実行結果:
Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    Recursive constructor invocation Person(String, int)
    Recursive constructor invocation Person()
    Recursive constructor invocation Person(String)

    at com.wz.thisdemo.Person.(TestDemo.java:6)
    at com.wz.thisdemo.TestDemo.main(TestDemo.java:23)

以上のコードと実行結果から、コンストラクタが再帰的に呼び出されていることがわかります.
したがって、1つのクラスに複数の構造メソッドが存在し、これらの構造メソッドがthis()を使用して互いに呼び出されている場合、少なくとも1つの構造メソッドがプログラムの出口として呼び出されていないことを保持しなければならない.
構造方法の相互運用の例を見てみましょう.従業員クラス(従業員番号、氏名、給与、部門)を定義します.このクラスでは4つの作業方法を提供します.A、単参、従業員番号のみを伝達すると、従業員の名前:無名氏、給与:0、部門:未定B、双参、従業員番号、氏名を伝達すると、従業員の給与は1000、部門:後方勤務C、四参、従業員番号、名前、部門、給料D、無参を渡すと、すべて空の値でコードを見に来ます.
package com.wz.thisdemo;
class Emp {
    private int empno ;
    private String ename ;
    private double salary ;
    private String dept ;
    public Emp(){}
    public Emp(int empno){
              this.empno = empno ;
              this.ename = "   " ;
              this.salary = 0.0 ;
              this.dept = "  " ;
    }
    public Emp(int empno,String ename){
              this.empno = empno ;
              this.ename = ename ;
              this.salary = 1000.0 ;
              this.dept = "  " ;
    }
    public Emp(int empno,String ename,double salary,String dept){
              this.empno = empno ;
              this.ename = ename ;
              this.salary = salary ;
              this.dept = dept ;
    }
    public String getInfo() {
              return "    :" + this.empno + ",  :" + this.ename + ",  :" + this.salary + ",  :" + this.dept ;
    }
}

public class TestDemo {
    public static void main(String args[]) {
        Emp emp1 = new Emp();
        System.out.println(emp1.getInfo());

        Emp emp2 = new Emp(4555);
        System.out.println(emp2.getInfo());

        Emp emp3 = new Emp(6542,"  ");
        System.out.println(emp3.getInfo());

        Emp emp4 = new Emp(4578,"  ",12000,"   ");
        System.out.println(emp4.getInfo());

    }
}

実行結果:
0,  :null,  :0.0,  :null4555,  :   ,  :0.0,  :  
    :6542,  :  ,  :1000.0,  :  
    :4578,  :  ,  :12000.0,  :   

以上のように開発すれば,機能の実現は可能であるが,コードには重複するコードが存在し,明らかに不適切である.そこで,構造方法の相互変調により,構造方法を以下のように変更する.
    public Emp(){}

    public Emp(int empno){
              this(empno,"   ",0.0,"  ") ;//        
    }
    public Emp(int empno,String ename){
              this(empno,ename,1000.0,"  ") ;//        
    }

    public Emp(int empno,String ename,double salary,String dept){
              this.empno = empno ;
              this.ename = ename ;
              this.salary = salary ;
              this.dept = dept ;
    }

実行結果は次のとおりです.
0,  :null,  :0.0,  :null4555,  :   ,  :0.0,  :  
    :6542,  :  ,  :1000.0,  :  
    :4578,  :  ,  :12000.0,  :   

このコンストラクションメソッドの相互呼び出しは,オブジェクトがインスタンス化されたときに,異なるコンストラクションで同じ操作がいくつかある場合に用いる.
三、thisは現在のオブジェクトを表す
現在のオブジェクトとは、クラス内のメソッドを現在呼び出しているオブジェクトです.
まずコードを見てみましょう.
package com.wz.thisdemo;

class Book{

}
public class TestDemo {
    public static void main(String args[]) {
        Book booka = new Book();
        System.out.println(booka);

        Book bookb = new Book();
        System.out.println(bookb);

    }
}

実行結果:
com.wz.thisdemo.Book@15db9742
com.wz.thisdemo.Book@6d06d69c

Bookクラスにthisを印刷する方法を追加します.
package com.wz.thisdemo;

class Book{
    public void print(){
        //this            
        System.out.println("this = "+ this);
    }
}
public class TestDemo {
    public static void main(String args[]) {
        Book booka = new Book();
        System.out.println(booka);
        booka.print();

        System.out.println();

        Book bookb = new Book();
        System.out.println(bookb);
        bookb.print();

    }
}

実行結果:
com.wz.thisdemo.Book@15db9742
this = com.wz.thisdemo.Book@15db9742

com.wz.thisdemo.Book@6d06d69c
this = com.wz.thisdemo.Book@6d06d69c

では、以前の「this.プロパティ」は実際には現在のオブジェクトのプロパティであり、スタックメモリに保存されている内容に違いありません.