Java学习6:this(隐式参数)关键字内存分析详解及用法

来源:互联网 发布:js 全局变量 丢失属性 编辑:程序博客网 时间:2024/06/03 21:29

this关键字,是一个隐式参数

1.概述

this关键字,是一个隐式参数,另外一个隐式参数是super。
this用于方法里面,用于方法外面无意义。
this关键字一般用于set方法和构造方法中。
下面从内存分析的角度去理解this关键字,然后关注其常见用法。

2.this关键字内存分析

2.1分析代码

首先创建一个类Student和一个测试类Test:

public class Student {    int age;    String name;    public Student() {    }    public Student(int age) {        this.age = age;    }    public void sayHello() {        this.name = "zhangsan";        System.out.println(name);    }}
public class Test {    public static void main(String[] args) {        Student stu = new Student();        stu.sayHello();    }}

2.2代码分析

细节的内存分析可参考:图解Java内存分析 。
这里仅针对this相关进行分析。

1.Student stu = new Student();

我们通过new关键字生成一个stu局部变量对象。

2.stu.sayHello();

调用sayHello()方法。这里我们假设new Student实例的地址是:23232323(自己随便写的无意义的地址)。
那么stu变量就是通过该地址访问到该实例。进而通过该实例访问sayHello()方法。

3.this.name = “zhangsan”;(sayHello)

在sayHello()方法中,我们将”zhangsan”常量的地址给该实例的name属性。
那我们给地址的时候就要判断是给哪一个实例,因为实例不止一个(我们可以new出很多对象)。这个时候我们在name前加一个this关键字,代表调用该方法的对象
简言之,这里的this代表的就是23232323的地址指向
那么我们再次回想,之前我们对变量的赋值其实是直接写的,并没有加this关键字,而且运行无问题,这是为什么呢?
事实上,在jvm编译时,对于无惨的方法,会自动在参数表中传入一个参数:this。这种参数叫做隐式参数,另一个常见的隐式参数是super。

这里写图片描述

因而,在普通方法中,this关键字加与不加并没区别,下面我们将介绍this关键字的用法。

3.this关键字的用法

3.1用于构造方法中属性的初始化

在Student类中有参构造方法中

    public Student(int age) {        this.age = age;    }

我们采用this.age = age来对age属性初始化。name这里的this是必须的吗?
我们尝试去掉this关键字。虽然不会报错,但是IDE会警告提示:

The assignment to variable age has no effect

age属性并没有改变,为什么?因为根据Java的就近原则,第一个age指的就是参数列表中的age,第二个age也是参数列表中的age,即,自己赋值给自己。
所以此处的this关键字不能省略。这里的this代表的是:正要初始化的对象

3.2用于set方法

对Student类添加一个age的set函数,并把age属性改为私有的private。

public class Student {    private int age;    String name;    public Student() {    }    public Student(int age) {        this.age = age;    }    public void sayHello() {        this.name = "zhangsan";        System.out.println(name);    }    public void setAge(int age) {        this.age = age;    }}

与构造方法中的this一样,这里的this也不能省略,这里的this代表:代表调用该方法的对象

3.3调用构造方法:this()

假如我们想在Student(int age)方法中调用无参的构造器Student();
可通过以下方式:

    public Student(int age) {        this(); // 调用另一个构造器,但必须位于首行代码        this.age = age;    }

这里this()必须位于首行代码。否则报错:

Constructor call must be the first statement in a constructor

当然,含参的构造器也可以调用含参的构造器,传参数即可。

    Student(int age, String name) {        this(age);        this.name = name;    }

3.4static方法中使用this关键字:不可以

我们在static方法中使用this关键字,看下效果:

    public static void tell(int age) {        this.age = age;    }

报错,信息

Cannot use this in a static context

其实很好理解,因为静态方法位于方法区中,就没有对象,所以就没有代表this的对象。

小结

  • this关键字在普通方法里加和不加含义相同
  • 在普通方法中,this总是指向调用该方法的对象
  • 构造方法中,this总是指向正要初始化的对象
  • 构造方法调用构造方法可通过this(),可传参数,但必须位于首行
  • this不能用于static方法,static中没有对象