Java中this和super的区别及this能否调用到父类使用
作者:??Java中文社群???? 发布时间:2023-01-05 12:03:13
前言:
this 和 super 都是 Java 中常见的关键字,虽然二者在很多情况下都可以被省略,但它们在 Java 中所起的作用是不可磨灭的。它们都是用来起指代作用的,每个类在实例化的时候之所以能调用到 Object 类(Object 类是所有类的父类),全是二者的“功劳”。
1.super 关键字
super 是用来访问父类实例属性和方法的。
1.1 super 方法使用
每个实例类如果没有显示的指定构造方法,那么它会生成一个隐藏的无参构造方法。对于 super() 方法也是类似,如果没有显示指定 super() 方法,那么子类会生成一个隐藏的 super() 方法,用来调用父类的无参构造方法,这就是咱们开篇所说的“每个类在实例化的时候之所以能调用到 Object 类,就是默认 super 方法起作用了”,接下来我们通过实例来验证一下这个说法。
PS:所谓的“显示”,是指在程序中主动的调用,也就是在程序中添加相应的执行代码。
public class SuperExample {
// 测试方法
public static void main(String[] args) {
Son son = new Son();
}
}
/**
* 父类
*/
class Father {
public Father() {
System.out.println("执行父类的构造方法");
}
}
/**
* 子类
*/
class Son extends Father {
}
在以上代码中,子类 Son 并没有显示指定 super() 方法,我们运行以上程序,执行的结果如下:
从上述的打印结果可以看出,子类 Son 在没有显示指定 super() 方法的情况下,竟然调用了父类的无参构造方法,这样从侧面验证了,如果子类没有显示指定 super() 方法,那么它也会生成一个隐藏的 super() 方法。这一点我们也可以从此类生成的字节码文件中得到证实,
如下图所示:
super 方法注意事项:
如果显示使用 super() 方法,那么 super() 方法必须放在构造方法的首行,否则编译器会报错,
如下代码所示:
如上图看到的那样,如果 super() 方法没有放在首行,那么编译器就会报错:提示 super() 方法必须放到构造方法的首行。 为什么要把 super() 方法放在首行呢? 这是因为,只要将 super() 方法放在首行,那么在实例化子类时才能确保父类已经被先初始化了。
1.2 super 属性使用
使用 super 还可以调用父类的属性,比如以下代码可以通过子类 Son 调用父类中的 age 属性,
实现代码如下:
public class SuperExample {
// 测试方法
public static void main(String[] args) {
Son son = new Son();
}
}
/**
* 父类
*/
class Father {
// 定义一个 age 属性
public int age = 30;
public Father() {
super();
System.out.println("执行父类的构造方法");
}
}
/**
* 子类
*/
class Son extends Father {
public Son() {
System.out.println("父类 age:" + super.age);
}
}
以上程序的执行结果如下图所示,在子类中成功地获取到了父类中的 age 属性:
2.this 关键字
this 是用来访问本类实例属性和方法的,它会先从本类中找,如果本类中找不到则在父类中找。
2.1 this 属性使用
this 最常见的用法是用来赋值本类属性的,比如常见的 setter 方法,如下代码所示:
上述代码中 this.name 表示 Person 类的 name 属性,此处的 this 关键字不能省略,如果省略就相当于给当前的局部变量 name 赋值 name,自己给自己赋值了。我们可以尝试一下,将 this 关键字取消掉,
实现代码如下:
class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class ThisExample {
public static void main(String[] args) {
Person p = new Person();
p.setName("磊哥");
System.out.println(p.getName());
}
}
以上程序的执行结果如下图所示:
从上述结果可以看出,将 this 关键字去掉之后,赋值失败,Person 对象中的 name 属性就为 null 了。
2.2 this 方法使用
我们可以使用 this() 方法来调用本类中的构造方法,具体实现代码如下:
public class ThisExample {
// 测试方法
public static void main(String[] args) {
Son p = new Son("Java");
}
}
/**
* 父类
*/
class Father {
public Father() {
System.out.println("执行父类的构造方法");
}
}
/**
* 子类
*/
class Son extends Father {
public Son() {
System.out.println("子类中的无参构造方法");
}
public Son(String name) {
// 使用 this 调用本类中无参的构造方法
this();
System.out.println("子类有参构造方法,name:" + name);
}
}
以上程序的执行结果如下图所示:
从上述结果中可以看出,通过 this() 方法成功调用到了本类中的无参构造方法。
注意:this() 方法和 super() 方法的使用规则一样,如果显示的调用,只能放在方法的首行。
2.3 this 访问父类方法
接下来,我们尝试使用 this 访问父类方法,具体实现代码如下:
public class ThisExample {
public static void main(String[] args) {
Son son = new Son();
son.sm();
}
}
/**
* 父类
*/
class Father {
public void fm() {
System.out.println("调用了父类中的 fm() 方法");
}
}
/**
* 子类
*/
class Son extends Father {
public void sm() {
System.out.println("调用子类的 sm() 方法访问父类方法");
// 调用父类中的方法
this.fm();
}
}
以上程序的执行结果如下:
从上述结果可以看出,使用 this 是可以访问到父类中的方法的,this 会先从本类中找,如果找不到则会去父类中找。
3.this 和 super 的区别
3.1 指代的对象不同
super 指代的是父类,是用来访问父类的;而 this 指代的是当前类。
3.2 查找范围不同
super 只能查找父类,而 this 会先从本类中找,如果找不到则会去父类中找。
3.3 本类属性赋值不同
this 可以用来为本类的实例属性赋值,而 super 则不能实现此功能。
3.4 this 可用于 synchronized
因为 this 表示当前对象,所以this 可用于 synchronized(this){....} 加锁,而 super 则不能实现此功能。
来源:https://juejin.cn/post/7046994591253266440
猜你喜欢
- foreach 循环 list(map)直接上代码:整体需求就是1.分页对象里面有map map里面又有数组对象2.分页对象里面有list
- 项目需要去调用.NET的WebSrevice,本身是Java,研究了半天,终于有些头绪,记下来。1,新建.NET WebService。只在
- 我对java中lambda表达式的看法是相当纠结的:一个我这么想:lambda表达式降低了java程序的阅读体验。java程序一直不以表现力
- List 是在开发中比较常用的集合,今天总结一下 Java 中初始化 List 的几种方式。1、常规方式List<String>
- MyBatis Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。Mybati
- 演示代码如下:package swt_jface.demo11; import org.eclipse.swt.SWT; import or
- 在基于UI元素的自动化测试中, 无论是桌面的UI自动化测试,还是Web的UI自动化测试. 首先我们需要查找和识别UI
- 1.什么是结构化编程编程中只使用三大结构不能使用goto语句1972年美国科学家,发表论文证明所有的程序流程,只需要三大结构完成。2.为什么
- 关于 swagger 本文不再赘述,网上文章很多。本文要讲的是Knife4j3.0.3 整合SpringBoot 2.6.4,因为 knif
- 本文实例为大家分享了java实现双色球抽奖的具体代码,供大家参考,具体内容如下实现双色球先考虑整体思路:1.随机生成7位数的数组为大奖号码(
- 这篇文章主要介绍了java获取当前时间的四种方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 周末这天手痒,正好没事干,想着写一个分页的例子出来给大家分享一下。这个案例分前端和后台两部分,前端使用面向对象的方式写的,里面用到了一些回调
- 本文实例讲述了Java链表(Linked List)基本原理与实现方法。分享给大家供大家参考,具体如下:在分析链表之前,我们先来对之前的动态
- 一、问题描述今天使用SDK Manager将Android SDK的版本更新到了Android 5.1的版本,eclipse创建androi
- 前言最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用LRU等淘汰机制,然后找了这方面的
- 前言插入排序狭义上指的是简单插入排序(选择集合,比较大小,插入元素),广义上还应该包括希尔排序(分治思想)及其两种实现方式,最激动人心的是
- 1: Nacos搭建可以参考 https://www.jb51.net/article/196842.htmSpringCloud 版本&l
- 简介对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等。虽然我们可以用一个固定的组件来做为AppBa
- 本项目主要实现对汽车维修厂的信息化管理功能,主要包含三个角色:管理员,维修师傅,客户。实现的主要功能包含用户管理、配置管理、汽车管理、故障管
- 概述ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是