Java初始化與清理
初始化與清理
1. 構造器中的this關鍵字
可能為一個類寫了多個構造器,有時想在一個構造器中呼叫另一個構造器,以免重複程式碼,可以使用this關鍵字實現。
for example
public class ConstructorsWithThis {
private int petalCount=0;
private String s ="initial value";
ConstructorsWithThis(int petals){
petalCount = petals;
System.out.println("Constructor int arg only,petalCount= " +petalCount );
}
ConstructorsWithThis(String ss){
System.out.println("Constructor int arg only,s= "+ss );
s=ss;
}
ConstructorsWithThis(String s,int petals){
this(petals);
//this(s);
this.s = s;
System.out.println("String & int args");
}
ConstructorsWithThis(){
this("hello",66);
System.out.println("default constructor (no args)");
}
public void printPetalCount() {
System.out.println("petalCount= "+petalCount+" s= "+s);
}
public static void main(String[] args) {
ConstructorsWithThis constructorsWithThis = new ConstructorsWithThis();
constructorsWithThis.printPetalCount ();
}
}
result
Constructor int arg only,petalCount= 66
String & int args
default constructor (no args)
petalCount= 66 s= hello
說明:
(1)ConstructorsWithThis(String s,int petals)表明:儘管可以使用this呼叫一個構造器,但是不能同時呼叫兩個。
(2)除了構造器外禁止在其他任何方法中呼叫構造器。
2. static的含義
在static方法的內部不能呼叫非靜態的方法,反過來倒是可以。
定義為static的東西只會被初始化一次。
在沒有建立任何物件的前提下,可以通過類本省呼叫static方法。這就像全域性方法。
3. 終結處理和垃圾回收
由於垃圾回收機制只知道回收釋放哪些經由new分配的記憶體,假如物件沒有通過new獲得了一塊特殊的記憶體,這時垃圾回收機制就不知怎麼去回收這部分特殊的記憶體。為了因對這種特殊的情況java允許在類中定義一個名為finalize()的方法。
finalize()的工作原理是:一旦垃圾回收器準備好釋放物件佔用的記憶體空間時,將首相呼叫finalize()方法,並在下一次垃圾回收動作發生時,才會正真回收物件佔用的記憶體。
垃圾回收的三點:
- 物件可能不被垃圾回收
- 垃圾回收並不等於“析構”
- 垃圾回收只與記憶體有關
finalize的用途
上面說到,finalize是作用與特殊情況,但是Java中一切皆物件,那麼這種特殊情況又指的是什麼呢?
看來之所以要用finalize是由於在分配記憶體時可能採取了類似於C語言的做法(malloc),而非java的方式。
4. 靜態資料的初始化
無論建立多少個物件,靜態資料都只佔用一份儲存空間。static關鍵字不能應用於區域性變數,它只能作用於域。如果一個域是靜態的基本型別域,且沒有對他進行初始化,那麼它就會獲得基本型別的標準初始值(對於數字,布林型,字元型 都是0;對於應用則是null)。
4.1 顯示的靜態初始化
public class Spoon{
static int i;
static{
i = 66;
}
}
跟在static關鍵字後面的程式碼只執行一次,當首次生成這個類的物件時,或者首次訪問屬於哪個類的靜態資料成員時(即使從未生成過那個類的物件)。
4.2 非靜態例項初始化
for example
public class message {
private String author;
private String content ;
{
author = "XXX";
content = "XXXXXXXX";
System.out.println("author & content initialized");
}
message(){
System.out.println("message()");
}
message(String author){
this.author = author;
System.out.println("message(String)");
}
@Override
public String toString() {
return "message [author=" + author + ", content=" + content + "]";
}
public static void main(String[] args) {
message m1 = new message();
System.out.println(m1.toString());
message m2 = new message("duqingqing0110");
System.out.println(m2.toString());
}
}
result
author & content initialized
message()
message [author=XXX, content=XXXXXXXX]
author & content initialized
message(String)
message [author=duqingqing0110, content=XXXXXXXX]
看起來它與靜態初始化句子一模一樣,只不過少了static關鍵字。這種語法對於支援匿名內部類的初始化是必須的。
5. 陣列的初始化
花括號括起來的列表初始化物件陣列,有兩種形式:
public class ArrayInitialization {
public static void main(String[] args) {
Integer[] a = { new Integer(1), new Integer(2), 3, };
Integer[] b = new Integer[] { new Integer(1), new Integer(2), 3, };
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
/**
* 這兩種形式中初始化列表的最後一個逗號都是可選的(這一特性使維護長列表變得更容易)
*/
[1, 2, 3]
[1, 2, 3]
5.1 可變引數列表
有了可變參,就再也不用顯示的寫陣列的語法了,當你指定引數時編譯器實際上會為你填充引數
for example
public class VariableParameterList {
public static void printArray(Object ... args) {
for(Object obj : args) {
System.out.print(obj+" ");
}
System.out.println();
}
public static void main(String[] args) {
printArray(new Integer(47),new Float(3.14),new Double(1024.001));
printArray("one","two");
printArray((Object[])new Integer[] {1,2,3,4,5,6});
}
}
result
47 3.14 1024.001
one two
1 2 3 4 5 6
6.列舉型別
Java SE5引入新關鍵字enum。下面列舉中國市場的貨幣面額。
public enum Money {
ONE,FIVE,TEN,TWENTY,FIFTY,HUNDRED
}
在建立enum的時候,編譯器會自動新增一些有用的特性。例如:
- toString()方法,以便直接列印enum的例項名字。
- ordinal()方法,用來表示某個特定的enum的宣告順序。
- static values()方法,用來按照enum的聲名順序,放回enum陣列。
public class EnumTest {
public static void main(String[] args) {
for(Money m : Money.values()) {
System.out.println(m+",Ordinal="+m.ordinal());
}
}
}
ONE,Ordinal=0
FIVE,Ordinal=1
TEN,Ordinal=2
TWENTY,Ordinal=3
FIFTY,Ordinal=4
HUNDRED,Ordinal=5