Java零基础快速入门|this关键字

本篇文章主要内容
this 是什么
this 使用在实例方法中
this 使用在构造方法中
学习目标
理解this 是什么,this 能用在哪里,不能用在哪里,this 什么时候可以省略,什么时候不能省略,以及怎么通过构造方法调用当前类中其它的构造方法。掌握静态代码块的执行时机,变量什么时候声明为静态变量,什么时候声明为实例变量,方法什么时候声明为实例方法,什么时候声明为静态方法,以及静态方法中为何不能直接访问实例变量和实例方法。
知识框架

this 是什么
this 是java 语言中的一个关键字,它存储在内存的什么地方呢,一起来看一段程序:


以上程序的内存结构图如下所示:

this 可以看做一个变量,它是一个引用,存储在Java 虚拟机堆内存的对象内部,this 这个引用保存了当前对象的内存地址指向自身,任何一个堆内存的 java 对象都有一个this,也就是说创建100 个java 对象则分别对应100 个this。通过以上的内存图,可以看出“jack 引用”保存的内存地址是0x1111,对应的“this 引用”保存的内存地址也是 0x1111,所以“jack 引用” 和“this 引用”是可以划等号的。也就是说访问对象的时候jack.name 和this.name 是一样的, 都是访问该引用所指向对象的name 属性。
this 指向“当前对象”,也可以说 this 代表“当前对象”,this 可以使用在实例方法中以及构造方法中,语法格式分别为“this.”和“this(..)”。this 不能出现在带有static 的方法当中。
this 使用在实例方法中
我们来看看this 是否可以出现在static 的方法当中,请看以下代码以及编译结果:

编译报错,如下图所示:

通过以上的测试得知this 不能出现在static 的方法当中,这是为什么呢?首先static 的方法, 在调用的时候是不需要创建对象的,直接采用“类名”的方式调用,也就是说static 方法执行的过程中是不需要“当前对象”参与的,所以static 的方法中不能使用this,因为 this 代表的就是“当前对象”。
大家是否还记得在之前的“封装”过程中,曾编写属性相关的 set 和 get 方法,set 和 get 方法在声明的时候不允许带static 关键字,我们把这样的方法叫做实例方法,说到实例方法,大家肯定想到了实例变量,没错,实例变量和实例方法都是对象相关,必须有对象的存在,然后通过“引用”去访问。
为什么set 和 get 方法设计为实例方法呢?那是因为set 和get 方法操作的是实例变量,“不同的对象”调用 get 方法最终得到的数据是不同的,例如 zhangsan 调用 getName()方法得到的名字是 zhangsan,lisi 调用 getName()方法得到的名字是 lisi,显然 get 方法是一个对象级别的方法,不能直接采用“类名”调用,必须先创建对象,再通过“引用”去访问。
this 可以出现在实例方法当中,因为实例方法在执行的时候一定是对象去触发的,实例方法一定是对象才能去调用的,而this 恰巧又代表“当前对象”,所以“谁”去调用这个实例方法this 就是“谁”。测试一下,请看以下代码:


运行结果如下图所示:

以上代码的输出结果具体是什么不重要,重要的是可以看出谁和谁是相等的。运行结果和代码结合起来分析一下this:

通过以上内容的学习得知,this 可以使用在实例方法当中,它指向当前正在执行这个动作的对象。
大家是否还记得实例变量怎么访问?正规的访问方式是采用“引用.”去访问。请看下面的代码:


运行结果如下图所示:

将以上部分代码片段取出来进行分析:


把完整的代码拿过来:


运行结果如下图所示:

通 过以上 的测试 我们得 知: System.out.println(name + " is shopping!") 和System.out.println(this.name + " is shopping!")是等效的。也就是说在 shopping()这个“实例方法”当中直接访问“实例变量”name 就表示访问当前对象的 name。
换句话说在实例方法中可以直接访问当前对象的实例变量,而“this.”是可以省略的。“this.”什么时候不能省略呢?请看以 下代码:

你有没有看到 name=_name 这样的代码很丑陋,怎样可以优雅一些呢?请看:

以上代码当中 this.name = name,其中 this.name 表示实例变量 name,等号右边的 name 是局部变量 name,此时如果省略“this.”,则变成 name = name,这两个 name 都是局部变量(java 遵守就近原则),和实例变量 name 无关了,显然是不可以省略“this.”的。
最终的结论是,this 不能出现在 static 的方法中,可以出现在实例方法中,代表当前对象,大部分情况下 this 都是可以省略的,只有当在实例方法中区分局部变量和实例变量的时候不能省略。
接下来我们再来扩展一下 this 的使用,请看代码:


运行结果如下图所示:

通过以上的测试,可以看出在一个实例方法当中可以直接去访问其它的实例方法,方法是对象的一种行为描述,实例方法中直接调用其它的实例方法,就表示“当前对象”完成了一系列行为动作。例如在实例方法shopping()中调用另一个实例方法pay(),这个过程就表示jack 在选购商品,选好商品之后,完成支付环节,其中选购商品是一个动作,完成支付是另一个动作。接下来继续扩展,请看以下代码:

以上代码编译报错了,请看:

为什么会编译报错,在 main 方法中为什么无法直接访问变量 i?我们来分析一下,首先i 变量是实例变量,实例变量要想访问必须先创建对象,然后通过“引用”去访问,main 方法是static 的方法,也就是说 main 方法是通过“类名”去调用的,在 main 方法中没有“当前对象”的概念,也就是说 main 方法中不能使用this,所以编译报错了。那应该怎么修改呢?请看:

运行结果如下图所示:

通过以上的测试得知,在 static 的方法中不能直接访问实例变量,要访问实例变量必须先自己创建一个对象,通过“引用”可以去访问,不能通过 this 访问,因为在 static 方法中是不能存在 this 的。其实这种设计也是有道理的,因为 static 的方法在执行的时候是采用“类名”去调用,没有对象的参与,自然也不会存在当前对象,所以 static 的方法执行过程中不存在this。
那么在static 方法中能够直接访问实例方法吗?请看以下代码:

编译报错了,请看下图:

为什么在 main 方法中无法直接调用实例方法 doSome()呢?很简单,因为实例方法必须先创建对象,通过引用去调用,在以上的main 方法中并没有创建对象,更没有this。所以在main 方法中无法直接访问实例方法。结论就是:在 static 的方法中不能直接访问实例方法。怎么修改呢?同样需要先创建对象,请看:

运行结果如下图所示:

综上所述,我们需要记住这样的一个结论:this 不能使用在static 的方法中,可以使用在实例方法中,代表当前对象,多数情况下this 是可以省略不写的,但是在区分局部变量和实例变量的时候不能省略,在实例方法中可以直接访问当前对象实例变量以及实例方法,在static 方法中无法直接访问实例变量和实例方法。
this使用在构造方法中
this 还有另外一种用法,使用在构造方法第一行(只能出现在第一行,这是规定,记住就行),通过当前构造方法调用本类当中其它的构造方法,其目的是为了代码复用。调用时的语法格式是:this(实际参数列表),请看以下代码:



运行结果如下图所示:

我们来看看以上程序的无参数构造方法和有参数构造方法:

通过上图可以看到无参数构造方法中的代码和有参数构造方法中的代码是一样的,按照以上方式编写,代码没有得到重复使用,这个时候就可以在无参数构造方法中使用“this(实际参数列表);”来调用有参数的构造方法,这样就可以让代码得到复用了,请看:


还是使用以上的main 方法进行测试,运行结果如下:

在this()上一行尝试添加代码,请看代码以及编译结果:



通过以上测试得出:this()语法只能出现在构造方法第一行,这个大家记住就行了。
最后附Java零基础视频教程给大家,配合学习效果更佳!!

