Java編程思想: 初始化與清理

構造器與方法

構造器和類名一致, 是由於: 1.保證不和方法名衝突. 2.編譯器知道如何進行調用.java

默認構造函數: 1. 沒有任何參數. 2.沒有任何構造器時會默認生成, 保證類的對象會被初始化. 若是類定義了構造函數, 則不會生成默認構造函數.git

構造函數沒有返回值: 因此不能將構造器看作一個方法, 更應該看作建立類實例時必須執行的"代碼塊"(構造器其實是static方法).github

方法重載: 經過參數列表的不一樣進行方法的重載.函數

static: 與類有關, 而與類實例無關. 即static與this無關.this

this指針: 所操做對象的引用.spa

1. 在構造器調用構造器中, 必須使用this來引用構造器, 而非使用類名:指針

public class Test {
  private int i;
  Test() {
    System.out.println("hello");
  }
  Test(int aI) {
//    Test(); //ERROR
    this();
    i = aI;
  }

  public static void main(String[] args) {
    Test t = new Test(11);
  }
}

由於構造器是須要對象來調用的, 即便將構造器當作一個特殊的"方法", 咱們也須要一個實例對象來調用, 而this剛好可知足要求.code

2. 在構造器中, 不能同時調用兩次this, 並且this必須放在最起始處, 下例代碼有誤:對象

public class Test {
	private int i;
	private String s;
	Test(int i) {
		this.i = i;
		System.out.println("int:" + i);
	}
	Test(String s) {
		this.s = s;
		System.out.println("String:" + s);
	}
	Test(int i, String s) {
		this(i);
		// ERROR
		this(s);
	}
	public static void main(String[] args) {
	}
}

3. 不能在其它方法中調用構造函數:生命週期

public void show() {
	// ERROR
	this(0);
    // ERROR
	Test(0, "hello");
}

 

清理: 終結處理和垃圾回收

垃圾回收的工做方式

引用計數方式回收垃圾: 當有引用鏈接至對象時, 引用計數加1. 當引用離開做用域或被置爲null時, 引用計數減1. 垃圾回收在整個對象的生命週期中查看引用, 若是爲0則釋放. 但因爲存在"循環引用", 則通常現代語言不適用引用計數進行垃圾回收.

Java的對象存活於堆棧靜態存儲區. 針對存放在堆棧中的對象, 分配新對象僅僅是移動堆棧指針便可. 而因爲存在垃圾回收使得堆棧中的對象更加的緊湊, 致使分配存儲效率更高.

Java中垃圾回收機制基於: 中止-複製標記-清掃中來回切換的.

中止-複製: 對任何存活於堆棧靜態存儲區中的對象, 咱們能夠查找到全部指向此對象的"活"的引用. 而後在堆棧中分配一個大的內存塊, 將"活"的對象複製過去便可.

標記-清掃: 若是垃圾產生量過少, 進行復制會浪費空間. 這時候, 只要將全部"活"的對象進行標記, 所有標記完成後清理未標記的垃圾(這裏並未涉及到複製操做).

垃圾回收重要的三點:

1. 對象可能不被垃圾回收: 由於對象不必定在堆棧(使用new建立的對象)和靜態存儲區中.

2. 垃圾回收並不等於C++中的"析構": "析構"是徹底釋放資源, 而"垃圾回收"的主要做用在於整理堆棧空間, 提升分配對象內存的效率. 因此它不必定會釋放資源.

3. 垃圾回收只與內存有關.

 

finalize

finalize的工做原理是: 一旦垃圾回收器準備好釋放對象佔用的存儲空間, 將首先調用其finalize方法, 而且在下一次垃圾回收動做發生時, 纔會真正回收對象佔用的內存.

class Book {
  protected void finalize() {
    System.out.println("book: finalize");
  }
}
public class Ex_10 {
//  protected void finalize() {
//    System.out.println("finalize");
//  }
  public static void main(String[] args) {
    new Ex_10();
    new Book();
    System.gc();
  }
}

這就是爲何若是Ex_10中定義finalize, 則System.gc()將不會回收垃圾. 由於對象均在Ex_10中, 不能調用Ex_10的finalize, 從而致使Book的finalize也被抑制.

刪除Ex_10中的finalize, 則會調用Book的finalize, 畢竟Book在Ex_10對象以外.

 

初始化

對象的建立過程以下(假設有Dog類):

1. 在實例化對象(new Dog)或者經過Dog調用靜態方法/靜態域時, Java解釋器會定位Dog.class文件.

2. 載入Dog.class後, 執行靜態初始化.

3. 在執行new Dog後, 會在堆棧上分配足夠大的存儲空間.

4. 這塊存儲空間會被初始化爲零, 引用會被初始化爲null.

5. 執行字段定義的初始化工做.

6. 執行構造器.

 

習題答案:

https://github.com/leicj/books/tree/master/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3

相關文章
相關標籤/搜索