1. 程式人生 > >Java物件(例項)建立涉及到的記憶體分配及相關事宜

Java物件(例項)建立涉及到的記憶體分配及相關事宜

1 成員變數

成員變數和區域性變數不一樣,首先是作用域不同:成員變數的作用域在整個類裡,而成員變數的作用域在定義它的程式碼塊裡;其次是區域性變數沒有顯式初始化使用該區域性變數,編譯器會報錯,但是成員變數在沒有顯式初始化的時候,編譯器會為其初始化一個預設值。

2 引用

Java語言中除了基本資料型別(boolean, char, byte, short, int, long, float, double)外的變數型別成為引用型別。

3 物件(例項)建立涉及到的記憶體分配

Java在建立一個物件時,會分配兩塊記憶體,一塊記憶體位於Stack內,而另一塊記憶體位於Heap內。位於Stack內的那塊記憶體的內容記錄了Heap的位置資訊,也即Stack那塊內容指向對應的Heap裡面的那塊記憶體。

為什麼物件(例項)的記憶體是位於Heap內?我們知道,記憶體裡的Code區放置程式碼,Data區域放置靜態變數和字串常量,Stack放置區域性變數,Heap放置動態分配的記憶體。由於new出來的物件例項,在編譯的時候並不知道它需要多大的記憶體,只有在執行的時候才知道物件例項的記憶體大小,這種就是動態分配。一方面是因為Heap是放置動態分配的記憶體的,動態分配的物件例項固然是放置在其中,另一方面,也只有Heap才有足夠的記憶體進行動態分配記憶體。

/* Person.java */

public class Person {
	private int age;
	private int weight;

	Person(int age, int weight) {
		this.age = age;
		this.weight = weight;
	}

	public int getAge() {
		return age;
	}

	public int getWeight() {
		return weight;
	}

	public static void main(String[] args) {
		Person p = new Person(25, 50);
		System.out.println(p.getWeight());
		System.out.println(p.getAge());
	}
}


在上面這段程式碼裡,程式碼放在記憶體的code記憶體區域裡面,首先執行main方法,在Stack中申請了一塊記憶體,名為p,此時p的內容為null,然後new觸發Person的構造器(或者說呼叫構造方法),此時在Stack又申請了兩塊記憶體,一塊名為age,值為25,一塊名為weight,值為50。同時在Heap申請了一塊記憶體,記憶體裡面也有age和weight,這時把Stack的age和weight的值複製到對應的Heap中的age和weight,複製完成後,Stack的age和weight這兩塊記憶體就會清去(因為建構函式呼叫完,它們的生存期就結束),同時Stack的p指向Heap的Person例項記憶體,這樣就完成了一個物件的建立。

4 Java的建構函式

在沒有顯式為Java類定義建構函式時,Java編譯其會為Java類加上預設(無引數)的建構函式,但當你顯式定義了建構函式時,Java則不會為您新增預設構造器,當您使用預設構造器進行建立物件例項時,編譯器將報錯。

/* Person.java */

public class Person {
	private int age;
	private int weight;

	Person(int age, int weight) {
		this.age = age;
		this.weight = weight;
	}

	public int getAge() {
		return age;
	}

	public int getWeight() {
		return weight;
	}

	public static void main(String[] args) {
		//顯式定義了構造器不能再使用預設構造器
		//除非在自己新增預設構造器
		//Person person = new Person();
		Person p = new Person(25, 50);
		System.out.println(p.getWeight());
		System.out.println(p.getAge());
	}
}

修改後的版本:
/* Person.java */

public class Person {
	private int age;
	private int weight;

	Person() {}
	Person(int age, int weight) {
		this.age = age;
		this.weight = weight;
	}

	public int getAge() {
		return age;
	}

	public int getWeight() {
		return weight;
	}

	public static void main(String[] args) {
		Person person = new Person();
		System.out.println(person.getAge());
		System.out.println(person.getWeight());
		Person p = new Person(25, 50);
		System.out.println(p.getWeight());
		System.out.println(p.getAge());
	}
}