this的引用
首先我们先看看一个实例:
class Date{
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
year = year;
month = month;
day = day;
}
public void show(){
System.out.println("年:"+year+", 月份:"+month+", 日期:"+day);
}
}
public class TextDemo1 {
public static void main(String[] args) {
Date date = new Date();
date.setDate(2022,03,27);
date.show();
}
}
这个时候我们的结果是:
所以:我们可以推断出来,当接受传参的变量名和成员变量相同时,编译器会分辨不出来,到底谁是成员变量。
所以,我们就引用一个this
class Date{
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void show(){
System.out.println("年:"+this.year+", 月份:"+this.month+", 日期:"+this.day);
}
}
public class TextDemo1 {
public static void main(String[] args) {
Date date = new Date();
date.setDate(2022,03,27);
date.show();
}
}
我们不理解这个this的作用是什么?
我们看看这个this实际上就是将date的地址的哈希值传了过去。
所以我们这里的this就代表了date(成员名),所以我们加上了this,就能精准的分清楚哪个是成员变量还是传值的变量。
java编译器给每个“成员方法“增加了一个隐藏的引用类型参数,该引用参数指向当前对象(成员方法运行时调用该
成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明
的,即用户不需要来传递,编译器自动完成this引用是编译器自动添加的,用户在实现代码时一般不需要显式给出。
注意:this引用的是调用成员方法的对象。
但是,我们这里this的用法还是没用讲完,我们先往下继续走
对象的构造及初始化
通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
我们先回顾一下实例初始化:
public static void main(String[] args) {
Dog dog1 = new Dog(); //这个小括号是干嘛用的?
Dog dog2 = new Dog();
//类名 对象名 = new 类名();
}
我们刚开始都不知道这个小括号是干嘛的?
其实,这个小括号就是为了初始化准备的。
当程序中,没有构造方法的时候,编译器会帮我们默认提供一个不带参数的构造方法。
这个小括号就是为了调用构造方法的。
class Dog {
public String name;
public String color;
public Dog(){
System.out.println("这是一个不带参数的构造方法");
}
public void barks(){
System.out.println(name+"汪汪汪");
}
public void wag(){
System.out.println(name+"摇尾巴~~~");
}
}
public static void main(String[] args) {
Dog dog1 = new Dog();
Dog dog2 = new Dog();
//类名 对象名 = new 类名();
}
同时,我的构造方法还是可以重载的。就像方法的重载一样。
方法名相同,参数一定不一样,返回类型不重要(其实只要参数不一样就足以,构造方法的方法名一定要是类名,同时构造方法规定没有方法名)。
同时,如果我们写了构造方法,系统就不会帮我们自动生成了。
所以我们说实例化一个对象的时候:
1.为对象分配内存
2.调用合适的构造方法
(必须要有这两步,但是不是只有这两步)
1. 名字必须与类名相同
2. 没有返回值类型,设置为void也不行
3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
上述Date类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。
注意:一旦用户定义,编译器则不再生成。
我们再来回顾一下之前的重点知识:
1.构造方法 是没有返回值,方法名和类名相同
2.构造方法 不止一个,可以有多个,对个构造方法之间,构成了重载,但是只能调用一次
3.当我写了一个类之后,没有写构造方法的时候,编译器为我们默认生成一个不带参数的构造方法
4.当我们写了任何一个构造方法之后,编译器不再为我们提供不带参数的构造方法。
5.一个类 至少会有一个构造方法,就选你没写也有
6.构造方法的本质就是实例化对象的时候调用
实例化对象分为两部:
1.分配内存
2.调用合适的构造方法
this其实还是可以调用其他的构造方法(前提是构成了构造方法的重载)
class Date{
public int year;
public int month;
public int day;
public Date(){
//this调用
this(2021);
System.out.println("一个不带参数的构造方法");
}
public Date(int year){
this(2001,01);
this.year = year;
System.out.println("带两个参数的构造方法");
}
public Date(int year,int month){
this(2022,03,27);
this.year = year;
this.month = month;
System.out.println("带两个参数的构造方法");
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("带三个参数的构造方法");
}
public void show(){
System.out.println("年:"+this.year+", 月份:"+this.month+", 日期:"+this.day);
}
}
public class TextDemo1 {
public static void main(String[] args) {
Date date = new Date();
date.show();
}
我们都很奇怪,为什么会出现这个结果?
其实,这里的流程我们还是不太清楚。
所以我们这里就是函数的嵌套。但是和递归是没有关系的。
所以当构造方法中使用this来调用其他构造方法的时候会产生调用多个构造方法的效果。
this(...)必须是构造方法中第一条语句
不能形成环
初始化所分配的空间
即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如
数据类型 | 默认值 |
byte | 0 |
char | '\u0000' |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |