this关键字主要有以下三个方面的用途:
1、this表示本类属性
2、this表示本类方法
3、this表示当前对象
一、“this属性”表示本类属性
先看代码:
class Person {
String name;
int age;
public Person(String n, int a) {
age = a;
name = n;
}
public String getInfo() {
return "姓名:"+name+",年龄:"+age;
}
}
public class TestDemo {
public static void main(String[]args){
Person per = new Person("张三", 18);
System.out.println(per.getInfo());
}
}
运行结果:
姓名:张三,年龄:18
观察上面例子的构造方法:
public Person(String n, int a) {
age = a;
name = n;
}
这个时候的构造方法的目的是为类中的name和age两个属性初始化,可是这个方法上的两个参数,一个是字母n,一个是字母a,难免让人一头雾水,既然构造方法的两个参数是为了给name和age初始化,那么最好将其定义为name和age;
public Person(String name, int age) {
age = age;
name = name;
}
此时两个参数的名称有意义了。但这样一来,一个问题就出现了,当参数与类属性同名时,类中属性无法被正确赋值,发现属性没有内容了,因为在程序之中是以“{}”作为分界,采用的就进取用原则,所以现在为了可以明确的指定操作的是类中的属性的话,那么应该采用“this.属性”的形式完成。
public Person(String name, int age) {
this.age = age;
this.name = name;
}
建议:只要是调用本类中的属性,都使用"this.属性"的方式来进行。
二、this调用本类方法
一个类中的方法分为两种:
(1)普通方法:如果现在要调用的是本类方法,可以用“this.方法()”调用;
(2)构造方法:调用构造方法使用“this(参数...)”调用
1、this调用构造方法
如果一个类中存在多个构造方法(无参、一个参数、两个参数...多个参数),不管使用何种构造方法,都要求在实例化对象的时候输出提示信息
范例(多个构造函数):
class Person {
String name;
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;
}
public String getInfo() {
return "姓名:"+name+",年龄:"+age;
}
}
public class TestDemo {
public static void main(String[]args){
Person per = new Person("张三", 18);
System.out.println(per.getInfo());
}
}
运行结果:
一个新的Person类对象被实例化
姓名:张三,年龄:18
在上述例子中我们可以发现,此程序出现了大量的重复代码,显得冗余,而我们要尽量将代码写的优雅,尽量没有重复,在这种情况下就可以利用this()来完成
范例1(this调用构造方法):
class Person {
String name;
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;
}
public String getInfo() {
return "姓名:"+name+",年龄:"+age;
}
}
public class TestDemo {
public static void main(String[]args){
Person per = new Person("张三", 18);
System.out.println(per.getInfo());
}
}
运行结果:
一个新的Person类对象被实例化
姓名:张三,年龄:18
需要注意的是:所有构造方法是在实例化的时候被默认调用,而且是在调用普通方法之前,所以使用“this()”调用构造方法的操作,一定要放在方法的首行:
public Person(String name) {
this(); //调用无参构造,放在首行
this.name = name;
}
范例2:
class Person {
String name;
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;
}
public String getInfo() {
return "姓名:"+name+",年龄:"+age;
}
}
public class TestDemo {
public static void main(String[]args){
Person per = new Person("张三", 18);
System.out.println(per.getInfo());
}
}
运行结果:
Error:(21, 12) java: 递归构造器调用
递归调用了构造器。
所以,如果一个类中存在了多个构造方法的话,并且这些构造方法都使用了this()相互调用,那么至少要保留一个构造方法没有调用其他构造,以作为程序的出口。
再来看一个构造方法相互调用的实例:
定义一个员工类(编号、姓名、部门、薪水),在这个类中提供四个构造方法:
(1)无参:均为空值
(2)单参:只传递编号,员工姓名:某某,部门:未定,薪水:0
(3)双参:只传递编号、姓名,则员工部门:后勤、薪水为2000
(4)四参:传递编号、姓名、部门、薪水
范例3:
class Emplayee{
private int worknumber;
private String name;
private String dept;
private int salary;
public Emplayee() {
}
public Emplayee(int worknumber) {
this.worknumber = worknumber;
this.name = "某某";
this.dept = "未定";
this.salary = 0;
}
public Emplayee(int worknumber,String name) {
this.worknumber = worknumber;
this.name = name;
this.dept = "后勤";
this.salary = 2000;
}
public Emplayee(int worknumber,String name,String dept,int salary) {
this.worknumber = worknumber;
this.name = name;
this.dept = dept;
this.salary = salary;
}
public String getInfo() {
return "员工编号:"+this.worknumber+"、姓名:"+this.name
+"、部门:"+this.dept+"、工资:"+this.salary;
}
}
public class TestDemo2 {
public static void main(String[]args){
Emplayee em1 = new Emplayee();
System.out.println(em1.getInfo());
Emplayee em2 = new Emplayee(123);
System.out.println(em2.getInfo());
Emplayee em3 = new Emplayee(256, "张三");
System.out.println(em3.getInfo());
Emplayee em4 = new Emplayee(789, "王富贵", "技术部", 10000);
System.out.println(em4.getInfo());
}
}
运行结果:
员工编号:0、姓名:null、部门:null、工资:0
员工编号:123、姓名:某某、部门:未定、工资:0
员工编号:256、姓名:张三、部门:后勤、工资:2000
员工编号:789、姓名:王富贵、部门:技术部、工资:10000
同范例2一样出现了大量的重复代码,为了代码的优雅可读性,可以通过构造方法的相互调用进行如下改动:
class Emplayee{
private int worknumber;
private String name;
private String dept;
private int salary;
public Emplayee() {
}
public Emplayee(int worknumber) {
this(worknumber,"某某","未定",0);//调用四参构造方法
}
public Emplayee(int worknumber,String name) {
this(worknumber,name,"后勤",2000);
}
public Emplayee(int worknumber,String name,String dept,int salary) {
this.worknumber = worknumber;
this.name = name;
this.dept = dept;
this.salary = salary;
}
public String getInfo() {
return "员工编号:"+this.worknumber+"、姓名:"+this.name
+"、部门:"+this.dept+"、工资:"+this.salary;
}
}
运行结果:
员工编号:0、姓名:null、部门:null、工资:0
员工编号:123、姓名:某某、部门:未定、工资:0
员工编号:256、姓名:张三、部门:后勤、工资:2000
员工编号:789、姓名:王富贵、部门:技术部、工资:10000
这种构造方法的互相调用是在对象实例化的时候,不同的构造有一些相同的操作情况下去使用。
2、this调用普通方法
class Person {
String name;
int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
this.print();//调用普通方法
}
public String getInfo() {
return "姓名:"+name+"、年龄:"+age;
}
public void print() {
System.out.println("调用了普通方法");
}
}
public class TestDemo {
public static void main(String[]args){
Person per = new Person("王富贵", 18);
System.out.println(per.getInfo());
}
}
运行结果:
调用了普通方法
姓名:王富贵、年龄:18
虽然调用本类普通方法不需要加this也可以正常使用。但建议加上,目的是可以区分方法的来源(在继承中有用)
三、this表示当前对象
当前对象,是指当前正在调用类方法的对象
范例:
class Person {
}
public class TestDemo {
public static void main(String[]args){
Person per1 = new Person();
System.out.println(per1);
Person per2 = new Person();
System.out.println(per2);
}
}
运行结果:
com.wfg.demo.Person@1540e19d
com.wfg.demo.Person@677327b6
在Person类中加上一个打印this的方法:
class Person {
public void print() {
System.out.println("this = "+this);
}
}
public class TestDemo {
public static void main(String[]args){
Person per1 = new Person();
System.out.println(per1);
per1.print();
System.out.println("====华丽的分割线====");
Person per2 = new Person();
System.out.println(per2);
per2.print();
}
}
运行结果:
com.wfg.demo.Person@1540e19d
this = com.wfg.demo.Person@1540e19d
====华丽的分割线====
com.wfg.demo.Person@677327b6
this = com.wfg.demo.Person@677327b6
小结:
1、只要对象调用了本类中的方法,那么这个this就表示当前执行的对象。
2、this.属性 实际上就是当前对象的属性,一定是堆内存中保存的内容。