技术大佬:我去,你竟然还不会用 this 关键字
上一篇文章写的是 Spring Boot 的入门,结果有读者留言说,Java 都还没搞完,搞什么 Spring Boot,唬得我一愣一愣的。那这篇就继续来搞 Java,推出广受好评的我去系列第四集:你竟然还不会用 this 关键字。
“老大,能给说详细地说说 this 关键字吗,总感觉对这个关键字的认知不够全面。”小王又过来找我了,他问的态度很谦逊,很卑微,但我还是忍不住破口大骂:“我擦,小王,你丫的竟然不会用 this,我当初是怎么面试你进来的!”
小王被我这句话吓坏了,赶紧躲到自己岗位上改 bug 去了。我呢,加班加点开始写这篇文章,真良心用苦啊。在 Java 中,this 关键字指的是当前对象(它的方法正在被调用)的引用,能理解吧,各位亲?不理解的话,我们继续往下看。
看完再不明白,你过来捶爆我,我保证不还手,只要不打脸。
01、消除字段歧义
我敢赌一毛钱,所有的读者,不管男女老少,应该都知道这种用法,毕竟写构造方法的时候经常用啊。谁要不知道,过来,我给你发一毛钱红包,只要你脸皮够厚。
public class Writer {
private int age;
private String name;
public Writer(int age, String name) {
this.age = age;
this.name = name;
}
}
Writer 类有两个成员变量,分别是 age 和 name,在使用有参构造函数的时候,如果参数名和成员变量的名字相同,就需要使用 this 关键字消除歧义:this.age 是指成员变量,age 是指构造方法的参数。
02、引用类的其他构造方法
当一个类的构造方法有多个,并且它们之间有交集的话,就可以使用 this 关键字来调用不同的构造方法,从而减少代码量。
比如说,在无参构造方法中调用有参构造方法:
public class Writer {
private int age;
private String name;
public Writer(int age, String name) {
this.age = age;
this.name = name;
}
public Writer() {
this(18, "沉默王二");
}
}
也可以在有参构造方法中调用无参构造方法:
public class Writer {
private int age;
private String name;
public Writer(int age, String name) {
this();
this.age = age;
this.name = name;
}
public Writer() {
}
}
需要注意的是,this()
必须是构造方法中的第一条语句,否则就会报错。
03、作为参数传递
在下例中,有一个无参的构造方法,里面调用了 print()
方法,参数只有一个 this 关键字。
public class ThisTest {
public ThisTest() {
print(this);
}
private void print(ThisTest thisTest) {
System.out.println("print " +thisTest);
}
public static void main(String[] args) {
ThisTest test = new ThisTest();
System.out.println("main " + test);
}
}
来打印看一下结果:
print com.cmower.baeldung.this1.ThisTest@573fd745
main com.cmower.baeldung.this1.ThisTest@573fd745
从结果中可以看得出来,this 就是我们在 main()
方法中使用 new 关键字创建的 ThisTest 对象。
04、链式调用
学过 JavaScript,或者 jQuery 的读者可能对链式调用比较熟悉,类似于 a.b().c().d()
,仿佛能无穷无尽调用下去。
在 Java 中,对应的专有名词叫 Builder 模式,来看一个示例。
public class Writer {
private int age;
private String name;
private String bookName;
public Writer(WriterBuilder builder) {
this.age = builder.age;
this.name = builder.name;
this.bookName = builder.bookName;
}
public static class WriterBuilder {
public String bookName;
private int age;
private String name;
public WriterBuilder(int age, String name) {
this.age = age;
this.name = name;
}
public WriterBuilder writeBook(String bookName) {
this.bookName = bookName;
return this;
}
public Writer build() {
return new Writer(this);
}
}
}
Writer 类有三个成员变量,分别是 age、name 和 bookName,还有它们仨对应的一个构造方法,参数是一个内部静态类 WriterBuilder。
内部类 WriterBuilder 也有三个成员变量,和 Writer 类一致,不同的是,WriterBuilder 类的构造方法里面只有 age 和 name 赋值了,另外一个成员变量 bookName 通过单独的方法 writeBook()
来赋值,注意,该方法的返回类型是 WriterBuilder,最后使用 return 返回了 this 关键字。
最后的 build()
方法用来创建一个 Writer 对象,参数为 this 关键字,也就是当前的 WriterBuilder 对象。
这时候,创建 Writer 对象就可以通过链式调用的方式。
Writer writer = new Writer.WriterBuilder(18,"沉默王二")
.writeBook("《Web全栈开发进阶之路》")
.build();
05、在内部类中访问外部类对象
说实话,自从 Java 8 的函数式编程出现后,就很少用到 this 在内部类中访问外部类对象了。来看一个示例:
public class ThisInnerTest {
private String name;
class InnerClass {
public InnerClass() {
ThisInnerTest thisInnerTest = ThisInnerTest.this;
String outerName = thisInnerTest.name;
}
}
}
在内部类 InnerClass 的构造方法中,通过外部类.this 可以获取到外部类对象,然后就可以使用外部类的成员变量了,比如说 name。
06、关于 super
本来想单独写一篇 super 关键字的,但可写的内容不多。本质上,this 关键字和 super 关键字有蛮多相似之处的,所以,就放在 this 这篇文章的末尾说一说吧。
简而言之,super 关键字就是用来访问父类的。
先来看父类:
public class SuperBase {
String message = "父类";
public SuperBase(String message) {
this.message = message;
}
public SuperBase() {
}
public void printMessage() {
System.out.println(message);
}
}
再来看子类:
public class SuperSub extends SuperBase {
String message = "子类";
public SuperSub(String message) {
super(message);
}
public SuperSub() {
super.printMessage();
printMessage();
}
public void getParentMessage() {
System.out.println(super.message);
}
public void printMessage() {
System.out.println(message);
}
}
1)super 关键字可用于访问父类的构造方法
你看,子类可以通过 super(message)
来调用父类的构造方法。现在来新建一个 SuperSub 对象,看看输出结果是什么:
SuperSub superSub = new SuperSub("子类的message");
new 关键字在调用构造方法创建子类对象的时候,会通过 super 关键字初始化父类的 message,所以此此时父类的 message 会输出“子类的message”。
2)super 关键字可以访问父类的变量
上述例子中的 SuperSub 类中就有,getParentMessage()
通过 super.message
方法父类的同名成员变量 message。
3)当方法发生重写时,super 关键字可以访问父类的同名方法
上述例子中的 SuperSub 类中就有,无参的构造方法 SuperSub()
中就使用 super.printMessage()
调用了父类的同名方法。
07、总结
亲爱的读者朋友,我应该说得很全面了吧?我想小王看到了这篇文章后一定会感谢我的良苦用心的,他毕竟是个积极好学的好同事啊。
如果觉得文章对你有点帮助,请微信搜索「 沉默王二 」第一时间阅读,回复「并发」更有一份阿里大牛重写的 Java 并发编程实战,从此再也不用担心面试官在这方面的刁难了。
本文已收录 GitHub,传送门~ ,里面更有大厂面试完整考点,欢迎 Star。
我是沉默王二,一枚有颜值却靠才华苟且的程序员。关注即可提升学习效率,别忘了三连啊,点赞、收藏、留言,我不挑,嘻嘻。
技术大佬:我去,你竟然还不会用 this 关键字的更多相关文章
- 我去,你竟然还不会用 Java final 关键字
写一篇文章容易吗?太不容易了,首先,需要一个安静的环境,这一点就非常不容易.很多小伙伴的办公室都是开放式的,非常吵,况且上班时间写的话,领导就不高兴了:只能抽时间写.其次,环境有了,还要有一颗安静的心 ...
- 技术大佬:我去,你竟然还在用 try–catch-finally
二哥,你之前那篇 我去 switch的文章也特么太有趣了,读完后意犹未尽啊,要不要再写一篇啊?虽然用的是 Java 13 的语法,对旧版本不太友好.但谁能保证 Java 不会再来一次重大更新呢,就像 ...
- postman一些你不常用的实用技巧,竟然还能这么玩
序言 各位好啊,我是会编程的蜗牛,作为java开发者,平时调试接口的时候,肯定需要用到接口调试工具,或者Swagger之类的.Swagger的优势在于它可以将后台加的一些接口注释信息直接展示出来,但是 ...
- 技术大佬:我去,这个容易被忽略的小程序Image图片属性,竟然这么屌!
前段时间在做“高清壁纸推荐”小程序优化的时候,发现一个很实用的图片属性——能够实现最大化压缩图片大小.且图片质量最小的损失,在此之前一直没有注意.今天跟大家分享一下这个属性的用法,主要是让大家能够,意 ...
- 我去,你竟然还不会用 synchronized
二哥,离你上一篇我去已经过去两周时间了,这个系列还不打算更新吗?着急着看呢. 以上是读者 Jason 发来的一条信息,不看不知道,一看真的是吓一跳,上次我去是 4 月 3 号更新的,离现在一个多月了, ...
- 什么?你竟然还没有用这几个chrome插件?
前言 其实18年之前写过一篇关于chrome插件的文章,里面安利了4个chrome插件.鉴于这已经是9102年了,之前觉得好用的chrome插件跟新了解到的比起来,还是差了那么点味道.所以决定再更新一 ...
- 使用过Redis,我竟然还不知道Rdb
目录 使用过Redis,那就先说说使用过那些场景吧 Rdb文件是什么,它是干什么的 分析工具 小结 联想 推荐阅读 使用过Redis,那就先说说使用过那些场景吧 字符串缓存 //举例 $redis-& ...
- 蒲公英 · JELLY技术周刊 Vol.10 为什么你还不使用 TypeScript
登高远眺 天高地迥,觉宇宙之无穷 基础技术 直播延迟?为什么流媒体直播的延迟那么高 随着通信技术的发展,视频点播.直播业务也逐渐兴起.在这些业务形态中,流媒体技术扮演着重要的角色.但在实际使用中,即便 ...
- python怎么自学?今日头条技术大佬的真实经历分享
大家好,我是武州,27岁,目前在字节跳动担任Python后端工程师一职. (摆拍一下,假装是保安) 在开始今天的文章之前,不知道你们有没有遇到过这样的问题: 大学没学到什么实质技术,毕业后找不到高薪的 ...
随机推荐
- 苹果系统通过brew安装sshpass
默认使用brew install sshpass会出现Warning: MD5 support is deprecated and will be removedin a future version ...
- LNMP企业应用部署全过程(基于DEDE后台)
系统环境说明: os:centos 5.6 nginx:nginx-1.0.11 php:php-5.3.9 mysql:mysql-5.5.20 文档导读: 一 准备工作 二 基础软件包安装 三 安 ...
- CF--思维练习--CodeForces - 216C - Hiring Staff (思维+模拟)
ACM思维题训练集合 A new Berland businessman Vitaly is going to open a household appliances' store. All he's ...
- Codeforces Round #618 (Div. 2)-B. Assigning to Classes
Reminder: the median of the array [a1,a2,-,a2k+1] of odd number of elements is defined as follows: l ...
- 题目分享G 二代目
题意:有n组数,每组包含两个数,问在每组只能取一个的前提下能组成的最长的从1开始的连续自然数有几个? 分析:刚学了差分约束系统,很容易往转换成图的方向去想 将他读入的这n组数当成边读入 很容易会得到一 ...
- commons-logging slf4j log4j 区别
日志门面 1.Apache通用日志接口(commons-logging.jar) Apache Commons包中的一个,包含了日志功能,必须使用的jar包.这个包本身包含了一个Simple Logg ...
- 海外网站如何通过代理IP进行采集?
海外网站如何通过代理IP进行采集? 我们在做爬虫的时候,经常会遇到这种情况,爬虫最初运行的时候,数据是可以正常获取的,一切看起来都那么的美好,然而,不一会儿,就可能会出现403 Forbidden , ...
- 花店橱窗布置问题(FLOWER)
目录 问题描述 问题分析 Java代码实现 运行结果 今天老师上完课说所有花都要被放,这个算法还是考虑多了,包含了这个选择,代码就不给了,用dp思想就可以解决了. 问题描述 假设你想以最美观的方式 ...
- @RequestParam和@RequestBody和@PathVariable用法小结
@RequestParam 使用@RequestParam接收前段参数比较方便,前端传参的URL: url = "${ctx}/main/mm/am/edit?Id=${Id}&na ...
- yum安装mysql 之后问题
日志报错: 190412 15:56:50 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create ...