4. this引用
4.1 为什么要有this引用
先看一个日期类的例子:
public class Date {
public int year;
public int month;
public int day;
public void setDay(int y, int m, int d){
year = y;
month = m;
day = d;
}
public void printDate(){
System.out.println(year + "/" + month + "/" + day);
}
public static void main(String[] args) {
// 构造三个日期类型的对象 d1 d2 d3
Date d1 = new Date();
Date d2 = new Date();
Date d3 = new Date();
// 对d1,d2,d3的日期设置
d1.setDay(2020,9,15);
d2.setDay(2020,9,16);
d3.setDay(2020,9,17);
// 打印日期中的内容
d1.printDate();
d2.printDate();
d3.printDate();
}
}
以上代码定义了一个日期类,然后 main 方法中创建了三个对象,并通过 Date 类中的成员方法对对象进行设置和打印,代码整体逻辑非常简单,没有任何问题。
但是细思之下有以下两个疑问:
1. 形参名不小心与成员变量名相同 :
public void setDay ( int year , int month , int day ){
year = year ;
month = month ;
day = day ;
}
那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?估计自己都搞不清楚了。
2. 三个对象都在调用setData和printData函数,但是这两个函数中没有任何有关对象的说明,setData和printData函数如何知道打印的是那个对象的数据呢?
一切让this引用来揭开这层神秘的面纱。
4.2 什么是this引用
this 引用指向当前对象 ( 成员方法运行时调用该成员方法的对象 ) ,在成员方法中所有成员变量的操作,都是通过该 引用去访问 。
public class Data {
public int year;
public int month;
public int day;
public void setDay(int y,int m,int d){
this.year = y;
this.month = m;
this.day = d;
}
public void printData(){
System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
}
public static void main(String[] args) {
Data data = new Data();
data.setDay(2022,11,10);
data.printData();
}
}
4.3 this引用的特性
1. this 的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this 只能在 " 成员方法 " 中使用
3. 在 " 成员方法 " 中, this 只能引用当前对象,不能再引用其他对象
4. this 是 “ 成员方法 ” 第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this 负责来接收
5. 对象的构造及初始化
5.1 如何初始化对象
通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
public static void main(String[] args) {
int a;
System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a
要让上述代码通过编译,非常简单,只需在正式使用 a 之前,给 a 设置一个初始值即可。如果是对象:
public static void main(String[] args) {
Date d = new Date();
d.printDate();
d.setDate(2021,6,9);
d.printDate();
}
// 代码可以正常通过编译
5.2.2 构造方法的特性
1. 名字必须与类名相同
2. 没有返回值类型,设置为void也不行
3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次 ( 相当于人的出生,每个人只能出生一次 )
4. 构造方法可以重载 ( 用户根据自己的需求提供不同参数的构造方法 )。
5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
6. 构造方法中,可以通过this调用其他构造方法来简化代码