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");
    }

}

内存图

Java中通过this关键字调用构造方法的一些理解_第1张图片


内存图分析

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斧正。感谢~

 
 

你可能感兴趣的:(JAVA)