Java中通过this关键字调用构造方法的一些理解【浅析】 |
您所在的位置:网站首页 › 一周工作餐菜谱怎么做好看 › Java中通过this关键字调用构造方法的一些理解【浅析】 |
学习java时,理解的this关键字的实质是用来指向当前对象的一个指针。按照之前所学,理解它有以下三种用法加一个性质。
1.在构造方法中使用this
关键字this可以出现在类的构造方法中,代表使用该构造方法所创建的对象。 public class Tom { int leg; Tom(int n) { this.cry(); //可以省略this,将this.cry();写成cry(); leg = n; this.cry(); } void cry() { System.out.println("I'm Tom,I have " + leg +" legs"); } public static void main(String[] args) { Tom cat = new Tom(4); //当调用构造方法Tom时,其中的this对象就是cat } }
2.在实例方法中使用this
关键字this可以出现在类的实例方法中,代表使用使用该方法的当前对象。 实例方法中可以利用this操作成员变量和成员方法,默认格式如下: this.成员变量 this.方法 public class Tom { int leg; void evolution() { this.leg = 2; this.cry(); } void cry() { System.out.println("I'm Tom,I have " + leg +" legs"); } public static void main(String[] args) { Tom cat = new Tom(); cat.leg = 4; cat.cry(); cat.evolution(); //对象调用本方法时,修改了leg并调用类cry()方法 } }
3.区分成员变量和局部变量
如果在方法内局部变量的命名与实例变量的命名相同,根据内部屏蔽外部的原则,实例变量在这个方法内暂时失效。这是如果想在该方法中使用实例变量,则需要在变量名前显示的加上"this.",用来指明此变量是实例变量。默认格式如下(前者指示的是实例变量,后者指示的是局部变量): this.变量名= 变量名; public class Tom { int leg; void setleg(int leg){ this.leg = leg; //此处利用this区分了实例变量与局部变量。 } void cry() { System.out.println("I'm Tom,I have " + leg +" legs"); } public static void main(String[] args) { Tom cat = new Tom(); cat.setleg(4); cat.cry(); } }
4.类方法中不能使用this
类方法(或有static修饰的静态方法)中不能使用this关键字。因为这些方法是静态的,常驻内存。当程序执行,为这些方法在内存中开辟存储空间的时候,可能还没有任何对象诞生。this关键字也就失去了意义。
一直以来,我都以为this的作用都较为基础的止步于此。但在今天学习数据结构的过程中,我看到了这样的代码。 public class SeqList implements LList { private Object [] element; //对象数组 private int len; //顺序表长度 /**初始化顺序表*/ public SeqList(int size) {//size:顺序表大小 element = new Object[size]; this.len = 0; } /**默认初始化顺序表*/ public SeqList(){ this(64); //this.SeqList(size); } } public class SeqListTest { public static void main(String[] args) { SeqList sList = new SeqList(); } }在第二个构造方法中,可见 this(64); 这样的语句。 这是JDK1.7以上新支持的功能。但初见时我并不理解这样的语法,因为this语句在我的印象中只是用来指示当前对象的一个关键字。单纯的指示当前对象,如果在实例化执行构造方法的同时又调用另一个构造方法,是否会生成一个新的对象?然而结果又是显而易见的——只有一个对象生成,并具有设想中应该有的和内容。
那么这样的语法的底层又是怎样去实现的呢?这让我陷入了疑惑。
思索良久,看了一些别人的理解和想法,再利用一些小小的测试代码。我将我对这个问题的一些设想写在这里。 话不多说,先来复习一下构造方法执行时底层发生了什么。 1.构造方法入栈。在堆区为对象开辟存储空间,并为实例变量赋默认值。 2.执行构造代码块(静态或动态)、实例变量赋值赋值语句。在堆区为实例变量初始化。 3.执行构造方法剩余语句,修改堆区实例变量的初始值。 4.构造方法弹栈。
以上是一般构造方法执行时的底层表现,那么按我的理解叙述一下以下代码在执行时的底层表现。 public class Tom { int head = 0; int leg; public Tom(int leg){ this.leg = leg; } public Tom() { this(6); this.head = 3; } public static void main(String[] args) { Tom cat = new Tom(); System.out.println("I'm Tom,I have " + cat.head +" head"); System.out.println("I'm Tom,I have " + cat.leg +" legs"); } }内存图
内存图分析 0. JVM生成字节码并加载到方法区blablabla... 1.main方法入栈; 2.无参构造方法Tom入栈。JVM在堆区开辟存储空间,为实例变量head、leg赋初值0; 3.执行构造代码块(这里没有),以及初始化语句。为head赋初值0; 4.执行构造方法体。并在第一句通过this转入带参构造方法Tom(int leg),Tom(int leg)入栈; 5.因为this指向当前对象,所以执行构造器为leg赋值6,Tom(int leg)出栈。返回无参构造方法断点处继续执行,为head赋值3,Tom()出栈; 6.继续执行main方法,直至程序结束,main出栈。
可见,this(参数)这种语法可以完成对构造方法的调用~
这里附上构造方法中使用this调用另一构造方法的相关规则: (1)假如在一个构造方法中使用了this语句,那么它必须作为构造方法的第一条语句(不考虑注释语句)。 (2)只能在一个构造方法中使用this语句来调用类的其他构造方法,而不能在实例方法中用this语句来调用类的其他构造方法。 (3)只能用this语句来调用其他构造方法,而不能通过方法名来直接调用构造方法。
以上是本人对这个问题的一些理解。若有不正确,请各位dalao斧正。感谢~ |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |