this
1.认识this
this是只向当前对象的引用(即是方法运行时,调用的对象),在成员方法中,所有变量的操作都是经过this引用去操作的。对于用户来说,这个操作时透明的,都是由编译器自主完成的。
下面看如下代码:
public class Date {
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 printDate(){
System.out.println(year+"/"+month+"/"+day+"/");
}
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
Date date3 = new Date();
date1.setDay(2024,1,1);
date2.setDay(2024,2,2);
date3.setDay(2024,3,3);
date1.printDate();
date2.printDate();
date3.printDate();
}
我们可以看到this引用的是调用该方法的对象。
this引用(Date@497),便是date。 ps:图中未用红线标注,文字表述。
2.为什么要用this引用
发现一个问题:
1.如果形参和成员变量名相同
代码如下:
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year,int month,int day) {
year = year;
month = month;
day = day;
}
public void printDate(){
System.out.println(year+"/"+month+"/"+day+"/");
}
public static void main(String[] args) {
Date date1 = new Date();
date1.setDay(2024,1,1);
date1.printDate();
}
}
没有this引用会出现如下结果:
在成员变量名前加上this之后,小伙伴们可以尝试以下 ,结果会正常。
2.如果setDate和printData,没有对对象有任何相关说明,如何能够知道数据的引用是否正确。
代码如下:
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) {
Date date1 = new Date();
Date date2 = new Date();
Date date3 = new Date();
date1.setDay(2024,1,1);
date2.setDay(2024,2,2);
date3.setDay(2024,3,3);
date1.printDate();
date2.printDate();
date3.printDate();
}
}
这边先不给出结果,但是 打印的结果都是正常的
3.this的特性
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this只能在"成员方法"中使用
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收
编译器会隐藏的this还原,在方法中,所有成员变量的访问都是通过this来完成
注意:如果形参和成员变量名一致的情况下就一定要使用this引用否则编译器分不清谁引用的谁
对象的构造方法及初始化
1.如何初始化
在所学知识我们知道,每个变量在创建时都必须初始化,否则跑不过编译器。但是在类中如果不初始化也能跑过,这个我们后续再说。
如果是对象呢,在本章上面的代码中都是使用setDate来给对象的成员进行赋值的,如果每new一个对象都要自己调用一次setDate,是不是会觉得很麻烦。其实有更便捷的方法,拿便是构造方法。
构造方法:构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且 在整个对象的生命周期内只调用一次。
public class Date {
public int year;
public int month;
public int day;
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = 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) {
Date date1 = new Date(2024,2,22);
date1.printDate();
}
}
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
关于构造方法还有必须要清楚的特性:
1.构造方法没有返回值,void也不行。
2.构造方法必须和类名相同
3.构造方法自对象的创建开始只执行一次
4.构造方法可以重载
//带三个参数的构造方法 public Date(int year,int month,int day){ this.year = year; this.month = month; this.day = day; } //无参的构造方法 public Date(){ this.year = 2023; this.month = 2; this.day = 22; }
5.如果没有定义显示的构造方法,编译器会默认生成一个没有参数的构造方法(用户一旦定义,编译器不再生成)
6. 构造方法中,可以通过this调用其他构造方法来简化代码
借用前面的代码
//带三个参数的构造方法 public Date(int year,int month,int day){ //this.year = year; //this.month = month; // this.day = day; this(2024,2,22);//必须在第一条语句 } //无参的构造方法 public Date(){ this.year = 2023; this.month = 2; this.day = 22; }
但是不能成环
//带三个参数的构造方法 public Date(int year,int month,int day){ this(); } //无参的构造方法 public Date(){ this(2024,2,22); }
除了构造方法初始化还有就是 直接就地初始化
在声明成员变量时,就直接给出了初始值。
代码如下:
public class Date { public int year = 2024; public int month = 1; public int day = 11; public Date(int year,int month,int day){ this.year = year; this.month = month; this.day = day; } public void printDate(){ System.out.println(year+" "+month+" "+day); } public Date(){ } public static void main(String[] args) { Date date1 = new Date(2024,2,22); Date date2 = new Date(); date1.printDate(); date2.printDate(); } }
2.默认初始化
public class Date { public int year; public int month; public int day; public Date(int year,int month,int day){ this.year = year; this.month = month; this.day = day; } public Date(){ this.year = 2023; this.month = 2; this.day = 22; } 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) { Date date1 = new Date(2024,2,22); date1.printDate(); } }
接上回,为什么这里类成员变量没有初始化为什么程序还能正常运行,这里涉及知识比较复杂,涉及JVM,只要简单知道JVM在给程序分配空间是就已经给成员变量初始化好了,且每个类型的初始值是一致的,如图下: