this的含义
this代表当前对象,谁调用this所在的方法,this就代表谁
这句话非常重要
demo
以这段代码为例,setNum方法内部的this,setStr方法内部的this,还有构造方法ThisKeyword(int num, String str)内部的两个this
它们代表哪个对象?当前对象是谁?
public class ThisKeyword {
private int num;
private String str;
public void setNum(int num) {
this.num = num;
}
public void setStr(String str) {
this.str = str;
}
public ThisKeyword(int num, String str) {
this.num = num;
this.str = str;
}
public ThisKeyword() {
}
public static void main(String[] args) {
}
}
此时还不知道谁是this,
只有当真正运行这三个方法的时候,我们才能清楚到底是哪个对象
this代表当前对象,谁调用this所在的方法,this就代表谁
public static void main(String[] args) {
ThisKeyword t1 = new ThisKeyword();
t1.setNum(1);
t1.setStr("aaa");
ThisKeyword t2 = new ThisKeyword(2, "bbb");
}
当运行t1.setNum(1);
时,this代表t1对象,t1对象调用了this所在的setNum
方法,所以this代表t1对象
t1.setStr("aaa");
同上,ThisKeyword t2 = new ThisKeyword(2, "bbb");
同上
理解this代表当前对象是很简单的,但是这种机制的实现是很复杂的,需要结合JVM内存结构图
内存图
这张图的其他部分都不重要,重要的是红色的两个部分
其实每个对象其中都内置了一个隐藏的属性:this,它的值是当前对象的地址
当我们没有创建对象时,对象不存在,自然对象的堆内存地址也不存在,此时this的值也是不存在的
只有当我们在堆中创建对象之后,this才会被第一次赋值
①main方法栈帧进入虚拟机栈
②运行ThisKeyword t1 = new ThisKeyword();
无参构造方法ThisKeyword()
入栈,在堆内存中申请空间创造对象t1,t1对象的this值是0x111
此时我们发现,new一个对象居然产生了两个对象引用,供外界程序调用成员变量和成员方法的t1,以及供类内部调用其成员变量和成员方法的this
我们可以将其理解为同一个人,有一个中国名字,还有一个英文名字。
在国内(类内)我们作为他的同胞(类内部成员变量和成员方法),当然要叫他中国名字this;
在国外(类外)歪果仁(外界程序)不知道他的中国名字,所以叫他英文名字t1
对外我是马邦德,对内我是张牧之
③运行t1.setNum(1);
(最重要的一步)
setNum()方法栈帧入栈,首先方法形参num,作为局部变量进入栈帧,然后是this入栈,通过this的地址,找到堆内存中“当前对象”的位置,进而找到t1的num变量的位置,然后赋值
Java就近原则
如果没有this,this.num = num;
就会变成num = num;
,而根据Java的就近原则,编译器会认为这里的两个num都是形参num,我们通过IDEA可以很清楚的看到这一点
如果是等号左边的num是对象中的num,它应该是红色的,而现在全都是灰色的
就近原则的解决办法1:更改形参变量名
此时聪明的小伙伴一定会说,这是因为重名了,我们改掉形参的名字不就好了
这样确实可以,完全没问题
就近原则的解决办法2:this
如果我比较懒,就想让形参名和实参名相同,请问阁下会如何应对?
此时只能用this,区分形参和实参
实际上,this就是为此而诞生的,大家都懒得给形参起新名字
this的实际使用
this使用限制
this关键字不能用在static修饰的方法中,因为static代表类存储,而this代表当前对象
关于static请看我的另外一篇博客:JavaSE:static关键字详解
this与static
this关键字不能用在static修饰的方法中,因为static代表类存储,而this代表当前对象,有类不一定有对象
但是this能调用static修饰的变量和方法,原因是static修饰的变量和方法,存在对象共享机制
this的用法
this.属性名
方法的局部变量名和类的全局变量名相同时,我们用this来区分局部变量和全局变量
this代表当前对象,所以this调用的一定是对象能调用的变量,也就是成员变量
this.方法名
代表当前正在运行的对象调用该方法
this()
- 只能在构造器中使用,不能在构造器当中使用
- 而且只能在构造器的第一行使用
- this();表示调用无参构造,也可以调用有参构造器
- 不能互相调用,
比如这种写法就是禁止使用的,互相调用没完没了了
- 不能与super一起使用