一、一般形式
this 有两种形式:
1)不含参数列表,例如:this.age , this.speak() , this 等等
2)含参数列表,例如:this(10) , this("Hello World !") 等等
二、不含参数列表
this 关键字的由来
package com.example; public class Person{ public void speak(String s){ System.out.println(s); } }
package com.example; public class Test{ public static void main(String[] args){ Person p1 = new Person(); Person p2 = new Person(); p1.speak("This is p1"); p2.speak("This is p2"); } }
1)这里用 new 创建了两个 Person 对象,对象的引用分别是 p1 和 p2
2)p1 和 p2 都调用了 speak 方法,那么 speak 方法怎么知道是 p1 对自己进行调用还是 p2 对自己进行调用呢?其实编译器暗自把 “对象的引用” 作为第一个参数传递给 speak 方法,所以实际上 speak 方法调用的形式为:
- Person.speak(p1, "This is p1")
- Person.speak(p2, "This is p2")
3)从上面表述中我们知道,在 speak 方法中有对象的引用,那么我们怎么才能得到这个引用呢?答案是:使用 this 关键字。
返回对象的引用
package com.example; public class Animals{ private int number; public void setNumber(int n){ number = n; } public int getNumber(){ return number; } public Animals getObject(){ return this; //返回对象的引用 } }
package com.example; public class Test{ public static void main(String[] args){ Animals A1 = new Animals(); A1.setNumber(100); System.out.println("A1: number=" + A1.getNumber()); Animals A2 = A1.getObject(); // 使得 A2 与 A1 引用的对象相同 System.out.println("A2:number=" + A2.getNumber()); Animals A3 = new Animals(); System.out.println("A3:number=" + A3.getNumber()); } }
运行结果: A1: number=100 A2:number=100 A3:number=0
1)可以看到,A1 和 A2 中 number 的值都是100,而 A3 中 number 的值是0
2)看 Animals A2 = A1.getObject(); 这一行,A1 调用 getObject()方法,所以返回的 this 就是 A1,该行代码等同于 A2 = A1;
3)A1 和 A2 指向同一个对象,A3 指向另外一个对象,不同对象的内存区域不同,所以 A3 中 number 的值才会是默认值0
防止属性名称与局部变量名称冲突
package com.example; public class Person{ public String name; // 属性 public int age; public Person(String name, int age){ // 局部变量 this.name = name; this.age = age; } }
package com.example; public class Test{ public static void main(String[] args){ Person p = new Person("张三", 20); System.out.println("name: " + p.name); System.out.println("age: " + p.age); } }
运行结果: name: 张三 age: 20
1)可以看到,属性名称和构造器中的局部变量名称都是一样的
2)在构造器中用 this.name、this.age 表示属性名称,这样来和局部变量中的 name、age 加以区分
三、含参数列表
作用
含有参数列表的 this 的作用是:在一个构造器中调用另外一个构造器
使用注意事项
1)只能在构造器中调用
2)最多每个构造器只能调用一个
3)必须位于构造器的第一行
package com.example; public class Man{ private int age; private String name; public Man(){ this(20); //this("张三"); // error,构造器中最多只能调用一个 System.out.println("Man()"); } public Man(int age){ this("张三"); System.out.println("age: " + age); } public Man(String name){ System.out.println("name: " + name); //this(); // error,必须位于构造器的第一行 } public int getAge(){ //this(); // error,只能在构造器中调用 return age; } }
package com.example; public class Test{ public static void main(String[] args){ Man m = new Man(); } }
运行结果: name: 张三 age: 20 Man()
1)可以看到,调用含有参数的 this 时,必须遵守相应的原则才能够正确编译执行
2)事实上,this 的不同参数列表对应不同的构造器,例如:this(20) 对应的是 public Man(int age){...} 这个构造器
参考资料:
《Java 编程思想》第4版