JavaSE:this关键字(代码和内存图讲解)

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()

  1. 只能在构造器中使用,不能在构造器当中使用
  2. 而且只能在构造器的第一行使用
  3. this();表示调用无参构造,也可以调用有参构造器
  4. 不能互相调用,
    比如这种写法就是禁止使用的,互相调用没完没了了
    在这里插入图片描述
  5. 不能与super一起使用
  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值