this 关键字的作用:
(1)this 强调本类中的方法。
(2)表示类中的属性。
(3)使用 this 调用本来的构造方法。
(4)this 表示当前对象。
1 使用 this 调用本类中的属性
实例 1 代码:
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person(String name, int age) {
name = name; // name 到底是属性还是构造方法的参数
age = age; // age 到底是属性还是构造方法的参数
}
public String getInfo() { // 取得信息
return "姓名: "+name+", 年龄: "+age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三", 33); // 调用构造实例化对象
System.out.println(per1.getInfo());
}
}
运行结果截图:
从结果中可以发现,并没有把从构造方法中传递进去的参数值赋给属性,现在的构造方法并不能成功地把传递进去的值赋类中的属性。可见,在赋值时候属性 并不是明确地被指出,所以造成这种错误,而这种错误可以利用 this 关键字解决。
上面的代码构造函数中:name和 age 到底是属性还是构造方法的参数 ?
回答:都是方法中的参数,就近原则,参数离构造函数比较近,所以就选择了参数,而没有选类的属性。
实例 2 代码:this 关键字修改后代码
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person(String name, int age) {
this.name = name; // name 到底是属性还是构造方法的参数
this.age = age; // age 到底是属性还是构造方法的参数
}
public String getInfo() { // 取得信息
return "姓名: "+name+", 年龄: "+age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三", 33); // 调用构造实例化对象
System.out.println(per1.getInfo());
}
}
运行结果截图:
从程序的运行结果来看,达到了所需的目的,而在构造方法之中,因为已经明确地标出了类的两个属性:“this.name” 和 “this.age”,所以在进行赋值操作的时候也不会产生歧义。
2 使用 this 调用构造方法
如果一个类中有多个构造方法的话,也可以利用 this 关键字互相调用。
假设现在要求不管类中有多少个构造方法,只要对象一被实例化,就必须打印一行“一个新的 Person 对象被实例化”的信息出来,很明显,此时如果要再各个构造方法中编写此输出语句肯定不合适,所以此时就可以利用 this 的概念完成。如下代码:
实例 3 代码:使用 this 调用本类的构造方法
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person() {
System.out.println("一个新的 Person 对象被实例化");
}
public Person(String name, int age) {
this(); // 此处调用 Person 类中的无参构造方法
this.name = name; // name 到底是属性还是构造方法的参数
this.age = age; // age 到底是属性还是构造方法的参数
}
public String getInfo() { // 取得信息
return "姓名: "+name+", 年龄: "+age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三", 33); // 调用构造实例化对象
System.out.println(per1.getInfo());
}
}
运行结果截图:
实例 4 代码:错误代码的调用
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person() {
System.out.println("一个新的 Person 对象被实例化");
}
public Person(String name, int age) {
this.name = name; // name 到底是属性还是构造方法的参数
this.age = age; // age 到底是属性还是构造方法的参数
this(); // 错误的代码调用,只能放在构造函数首行,编译出错
}
public String getInfo() { // 取得信息
this(); // 错误的代码调用,只能放在构造函数首行,编译出错
return "姓名: "+name+", 年龄: "+age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三", 33); // 调用构造实例化对象
System.out.println(per1.getInfo());
}
}
相关截图:
以上的错误就是 this() 只能放在构造方法的首行
另外,对于 this 调用构造方法的时候一定要留一个构造方法作为出口,即程序中至少存在一个构造方法是不使用 this 调用其他构造方法的。
实例 5 代码:错误代码
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person() {
this("花木兰", 16); // 使用 this 关键字调用构造函数出现递归(recursive),编译出错
System.out.println("一个新的 Person 对象被实例化");
}
public Person(String name) {
this(); // 使用 this 关键字调用构造函数出现递归(recursive),编译出错
}
public Person(String name, int age) {
this(name); // 使用 this 关键字调用构造函数出现递归(recursive),编译出错
this.name = name; // name 到底是属性还是构造方法的参数
this.age = age; // age 到底是属性还是构造方法的参数
}
public String getInfo() { // 取得信息
return "姓名: "+name+", 年龄: "+age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三", 33); // 调用构造实例化对象
System.out.println(per1.getInfo());
}
}
相关截图:
以上的错误提示为递归调用了构造方法,所以在构造方法间互相调用的时候一定要留一个出口,一般都将无参构造方法作为出口,即在无参构造方法中最好不要去调用其他构造方法。
3 this 表示当前对象
以上已经为读者讲解了何时使用 this 调用属性,何时使用 this 调用方法,实际上除这些特性之外, this 最重要的特点就是表示当前对象,在 Java 中当前对象就是指当前正在调用类中的方法对象。
实例 6 代码:观察 this 表示当前对象
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public String getInfo() { // 取得信息
System.out.println("Person 类 --->"+this); // 直接打印 this
return null;
}
public static void main(String agrs[]) {
Person per1 = new Person();
Person per2 = new Person();
System.out.println("MAIN 方法 --->"+per1); // 直接打印对象
per1.getInfo();
System.out.println("-----------------");
System.out.println("MAIN 方法 --->"+per2); // 直接打印对象
per2.getInfo();
}
}
运行结果截图:
从程序的运行结果来看,直接打印对象和调用 getInfo() 方法打印的结果是一样的,而且在 getInfo() 方法中永远是一个 this 关键字,也就是说哪个对象调用了类中的方法,则 this 就表示哪个对象。下面通过一个实例,来分析 this 表示当前对象的用法。
实例 7 代码:比较对象
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
在此类中有 name 和 age 两个属性,现在要求产生两个 Person 对象,并且判断这两个对象是否相等,那么这个时候就会产生以下两个问题。
(1)如何进行对象的比较?
(2)在哪里进行对象的比较?
对于第 1 个问题从 String 相关知识可知,要想进行对象的比较,是必须比较其内容才可以,但是 Person 中现在并不能使用 equals()方法,所以此时就需要对每一个属性进行依次的判断,如果所有属性的内容相等了,那么就可以证明这两个对象相等,这一点可以通过如下的代码进行验证。
对象的第一种比较方式
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三",16); // 声明两个对象,内容完全相等
Person per2 = new Person("张三",16); // 声明两个对象,内容完全相等
// 直接在主方法中依次取得各个属性进行比较
if(per1.getName().equals(per2.getName())&& per1.getAge() == per2.getAge()) {
System.out.println("两个对象相等");
}else {
System.out.println("两个对象不相等");
}
}
}
运行结果截图:
以上的程序确实完成了两个对象的比较功能,但是,把所有功能的判断语法放在主方法中是不合适的,所以对象的比较应该放在 Person 类之中,而不应该放在 main() 方法中进行编写。
实例 8 代码:修改后的对象比较操作
package self.learn.thisDemo;
public class Person {
private String name; // 姓名
private int age; // 年龄
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public boolean compare(Person per) {
// 调用此方法时里面存在两个对象:当前对象、传入对象
Person p1 = this; // 表示当前调用方法的对象,为 per1
Person p2 = per; // 传递到方法中的对象,为 per2
if(p1 == p2) { // 首先比较两个地址是否相等
return true;
}
if( p2 == null) { // 判断对象是否为空
return false;
}
// 分别判断每一个属性是否相等
if(p1.name.equals(p2.name)&& p1.age == p2.age) {
return true;
}else {
return false;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String agrs[]) {
Person per1 = new Person("张三",16); // 声明两个对象,内容完全相等
Person per2 = new Person("张三",16); // 声明两个对象,内容完全相等
// 直接在主方法中依次取得各个属性进行比较
if(per1.compare(per2)) {
System.out.println("两个对象相等");
}else {
System.out.println("两个对象不相等");
}
}
}
运行结果截图:
以上程序 Person 类中定义了一个 Compare()方法,此方法的主要功能就是专门完成两个对象的比较操作,在比较操作时,首先进行地址的比较,如果两个对象的地址一样 ,则肯定是同一个对象,而如果地址不相等,则将属性一个个依次进行比较。
对象比较
对象的比较操作在开发中是一个重要的概念,其基本操作形式是不变的,所以一定要重点掌握。