java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序
this
this 表示当前对象
使用上细分的话,this有 this. 和this()的使用情况 ,下面我们开始细撸
this .
使用场景一: 在成员方法中,this.变量名 指带当前对象的变量,此时this.是可以省略的
输出 结果为 “3” ;
在method()方法中,this.i=3 和i=3意思相同
但注意, 如果在method()方法中,输入的是 int i=3.结果可以完全不同。 为什么呢?
~~很显然。这样做的意思是说在方法中,重新定义一个局部变量i.并非指代当前对象啊。
使用场景二 : 在成员方法中,传入的参数名称和成员变量相同时,因java中变量的就近原则,使用this,区分成员变量和传入值,此时呢是不能省略的。
输出 结果为 “3” 但如果此时method方法中 为i=i ,这样本身其实没有意思,但你要知道 ,形参(int i)会在栈中存储,会产生新的int i,这个变量会随着method方法弹栈后消亡,各成员变量i是俩码事
ps: 场景二的情况是传参名和成员变量名相同,this才不可以省略,那起另一个名不就行了?
没错。完全可以起其它名字。 但是为了增强代码的可读性,一般将参数的名称和成员变量的名称保持一致,所以this的使用频率在规范的代码内部应该很多。
this()
在构造器中使用,构造器间相互调用
图列说明:
1、先执行 main 方法,main 方法压栈,执行其中的 new Person(“张三”,23);
2、堆内存中开辟空间,并为其分配内存地址 0x33,,紧接着成员变量默认初始化(name=null age = 0);
3、拥有两个参数的构造方法(Person(String nm , int a))压栈,在这个构造
方法中有一个隐式的 this,因为构造方法是给对象初始化的,那个对象调用到这个
构造方法,this 就指向堆中的那个对象。
4、由于 Person(String nm , int a)构造方法中使用了 this(nm);构造方法
Person(String nm)就会压栈,并将“张三”传递给 nm。在 Person(String nm , int
a)构造方法中同样也有隐式的 this,this 的值同样也为 0x33,这时会执行其中
name = nm,即把“张三”赋值给成员的 name。当赋值结束后 Person(String nm ,
int a)构造方法弹栈。
5、程序继续执行构造方法(Person(String nm , int a)中的 age = a;这时会
将 23 赋值给成员属性 age。赋值结束构造方法(Person(String nm , int a)弹栈。
6、当构造方法(Person(String nm , int a)弹栈结束后,Person 对象在内存
中创建完成,并将 0x33 赋值给 main 方法中的 p 引用变量。
this 使用使用总结
在类的方法定义中使用的 this 关键字代表使用该方法的对象的引用。
this 即”自己”,代表对象本身,谁调用代表谁。在成员方法中或构造器中隐式
的传递。作用如下:
1、this 在构造器中只能放在第一行
2、this.属性避免属性和形参、局部变量同名,发生就近原则
3、this([实参列表]): 构造器的首行调用其他构造器。
4、this 可以看作是一个变量,它的值是当前对象的引用。(我的理解是 this(nm) 等同于 p.Person(nm) )
5、this 不能出现在被 static 修饰的内容中
6、构造方法不能相互调用(即你调用我、我调用你),会报错,类似死循环
super
super 有俩种用法 1. super. 2. super() 和this的用法很相同
所以呢~~ super的介绍的我就轻了,它的使用只是在继承关系下的this使用嘛
super .
当父类 和子类 存在相同成员属性时,为区分这种俩种成员属性,会super.来指代父类中的成员属性
super()
构造器中相互调用,需在构造器代码中的第一行
子类在new 对象,进行初始化(子类的构造器进行初始化 ),会自动调用父类的空构造(使用super() )。
特别说明;我们知道 ,类中会默认有一个空构造,所有子类在初始化时,会自动调用父类的空构造。
此时,在子类的构造器中,super(); 是可以省略的 ; 但当我们已经给父类创建了带参构造器,却没有创空构造器时,此时在初始化子类时,会报错,除非手动输入一个和我们在父类中定义相同参数类型的super()才可以,如super(int a);
如果你在充分理解this的使用后的情况下,还是对super的用法不清楚,那们通往java大神的的路过于崎岖,建议改行做项目经理吧(说好啊,我可没对项目经理有意见~)
下而详细介绍下在构造器中this()和super()相互调用执行顺序,这个可以啃啃
在构造器中this()和super()相互调用执行顺序:
分析:
new Son()时,进入Son类的空参构造器,在空参构造器中,this(3)调用同类重载构造器,进入
带参构造器中,有隐式super(),调用上层父类空参构造器,构造器中有this(39),调用同类重载构造器,进入带参构造器中,有隐匿super()
(Father类的父类为Object了,无打印信息),,然后就是一个一个的打印信息了
我们要明白一个道理,在有继承关系时,创建子类对象,无论调用无参还有带参构造,都会调用父类的构造器,对父类对象初始化(但是在
初始化父类对象前,先会执行子类中重载构造器中this()调用,执行后才会调用父类构造器,默认没有this()的构造器有隐式super(),当然也可
以指定构带参构造器)。初始化父类对象,默认进入父类的空参构造器中(此时子类构造器中有个隐匿surper()),但如果调用子类构造器中
第一行已经明确选择父类带参构造器,则进入父类带参构造器
还有一点也至关重要,当父类中有带参构造器,无空参构造,且子类中没有明确指出使用父类带参构造生成父类对象时,程序会默认使用
super()空参构造生成父类对象,此时程序会报错。原因很简单:当一个类手动加入了带参构造器,系统将不会再为你自动生成空参构造。这
时就需要我们为父类添加空参构造。
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
Other Q&A
1.为什么在构造器中this()和super()要放在代码的首行?
因为构造对象时,默认需要调用类的构造器来初始化对象,而只有产生了对象,后面才能对对象操作嘛。
是不是先有鸡,才能下蛋呢?
2.为什么在构造器中不能同时this()和super()?
嗯。它们俩个都要求放在首行,所有不能同时使用了。
但想想哦,它们是否需要同时出现呢?在构造器同级用this()调用时,最后肯定有一个“出口”,(总不能用this()循环调用闹着玩bug吧)那么,这个构造器“出口”中肯定没有this(), 它的首行其 实有一个隐式super(),指向上级父层构造器,当然你也可以指定成调用带参构造器(如super(int i))。 或者也可以这么看,当构造器中this()时,就会先进行同类构造器间的调用,如果没有this()时,就会默认有一个隐式super(),对上级父类构造器调用。
------------------------------------------------------------------------------------------------------------------------------------------------------
版权声明:本文为CSDN博主「_大帅_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ted_cs/article/details/82526056
java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序的更多相关文章
- 第4节 Scala中的actor介绍:1、actor概念介绍;2、actor执行顺序和发送消息的方式
10. Scala Actor并发编程 10.1. 课程目标 10.1.1. 目标一:熟悉Scala Actor并发编程 10.1.2. 目标二:为学习Akka做准备 注:Sca ...
- Java子父类间静态代码块、非静态代码块、构造方法的执行顺序
子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...
- java 数据类型:<泛型>在方法中和在构造器中的应用
背景: Java不允许我们把对象放在一个未知的集合中. import java.util.ArrayList; import java.util.List; /** * @ClassName Meth ...
- Java基础语法05-面向对象-封装-包-构造器-初始化
封装 面向对象三大特性:封装.继承.多态 封装的好处 1.调用者:方便使用/简化使用 2.设计者:安全,可控 隐藏对象内部的复杂性,只对外公开简单的接口.便于外界调用,从而提高系统的可扩展性.可维护性 ...
- Java初始化块及执行顺序
理解 初始化块又称为代码块.属于类中的第四大成员.本质上是一个方法,它也有方法体,但没有方法名,没有参数,没有返回,而且也不是通过对象或类名显式调用,而是通过隐式调用 是构造器的补充 语法 [修饰符] ...
- Unity脚本在层级面板中的执行顺序测试1
第二篇测试循环时和动态创建时的调用顺序:LINK 测试版本Unity4.6.因为新版本对Transform的排序做了改变,所以不排除旧版本的测试结果不一样.测试时,使用Awake中添加Debug.lo ...
- 【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- java中构造方法和方法super/this超类与子类中初始化顺序
java中构造方法和方法全面解析 我相信大多说人都对构造方法.方法不陌生,而且很了解,但我也相信有很多像我这样的没有一个很好很清晰很全面的认识,今天就把它整理如下,希望能给大家带来点方便与帮助,也希望 ...
- Java:面向对象(继承,方法的重写(overide),super,object类及object类中方法的重写,父子类代码块执行顺序)
继承: 1.继承是对某一匹类的抽象,从而实现对现实世界更好的建模. 2.提高代码的复用性. 3.extends(扩展),子类是父类的扩展. 4.子类继承父类可以得到父类的全部属性和方法.(除了父类的构 ...
随机推荐
- Java内存模型与垃圾回收笔记
内存模型 栈. 局部变量(基本类型)与对象引用:线程隔离.每个方法执行时会创建一个栈帧,存储局部变量等. 堆. 对象实例:线程共享. 方法区.类信息.常量(final).静态变量.符号引用: 线程共享 ...
- 9、组件注册-@Import-使用ImportSelector
9.组件注册-@Import-使用ImportSelector 9.1 @Import 源码: @Target(ElementType.TYPE) @Retention(RetentionPolicy ...
- java 正则《转载》
Java 正则表达式 正则表达式定义了字符串的模式. 正则表达式可以用来搜索.编辑或处理文本. 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别. 正则表达式实例 一个字符串其实就是一个简 ...
- 分页控件Webdiyer.MvcPager
MVC 1.安装控件 install-package Webdiyer.MvcPager 2.Cotroller using System; using System.Collections.Gene ...
- 如何获得div对象的绝对坐标
<script> function test() { var $div0 = $('#0'); va ...
- [Codevs] 矩形面积求并
http://codevs.cn/problem/3044/ 线段树扫描线矩形面积求并 基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上 下边+1,上边-1: 然后根据线段树的权值和与相邻两 ...
- win下安装jupyter遇到的问题
一:安装jupyter 1.首先要用管理员方式打开cmd,没用管理员打开后面安装不上. 2.安装jupyter.我用的是python3,所以用pip3 install jupyter进行安装. 3.安 ...
- c++ 实现等待5s
#include <stdio.h> /* puts, printf */ #include <time.h> /* time_t, struct tm, time, loca ...
- Echarts-复杂关系图(源码)
关系图: 代码: <!DOCTYPE html> <head> <meta charset="utf-8"> <script type=& ...
- overflow妙用--去除默认滚动条,内容仍可滚动
在开发中我们往往要去除默认滚动条,但是其在竖直方向的滚动效果仍然需要. <div id="parent"> <div id="child"&g ...