構造函數重載:重載三要素(參數數量、參數類型、參數的排列順序)。
基本數據類型的重載:如果實參比形參的類型小,數據會先提升,如果實參比形參大,那么要先進行強制類型轉換。
返回值類型不是重載的要素:理解之一是,構造函數要實現重載,但構造函數無返回值。另外調用函數的時候可以沒有返回值類型。
this關鍵詞的使用:
1、this只能用于方法內部,它負責返回調用這個方法的對象的引用。你可以把this對象的引用當成任何對象的引用。
2、this用于在構造函數中調用其他構造函數,但只能調用一個,且調用的代碼應放在程序最前面,否則編譯器會報錯。
3、this.s=s當類的數據成員與類的方法的參數同名時,使用this.s=s消除歧義。
static的含義:
它的意思是,這個方法沒有this,你不能在static方法里調用非static的方法,但你卻可以不通過對象,直接調用static方法。類的static方法只能訪問其它static方法static成員。垃圾回收:
java提供finalize()方法用于垃圾回收器回收前執行方法中的代碼進行非new所創建內存的清理。你可以自己定義類的finalize()方法。不過要注意java對象并不總是會被回收的。它不象C++一樣提供析構函數,可做到總是回收。java垃圾回收特點:
1、對象不一定會被垃圾回收器回收;
2、垃圾回收不是析構;
3、你可以自己寫方法時行垃圾回收;
4、垃圾回收只與內存有關;
5、垃圾回收和finalize()都是靠不住的,只要jvm還沒到快要耗盡內存的地步,它是不會浪費時間來回收垃圾以恢復內存的。
初始化的順序:初始化的順序是由變量在類的定義里面的順序所決定的。變量的定義可能會分散在類定義的各個地方,并且與方法的定義相互交錯,但是變量的初始化會先于任何方法,甚至是構造函數的調用。以下為例:
class Tag{
Tag(int marker){輸出結果為:
System.out.println("Tag("+marker+")");
}
}
class Card{
Tag t1 = new Tag(1);
Card(){
System.out.println("Card()");
t3 = new Tag(22);
}
Tag t2 = new Tag(2);
void f(){
System.out.println("f()");
}
Tag t3 = new Tag(3);
}
public class Clean {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Card t = new Card();
t.f();
}
}
Tag(1)
Tag(2)
Tag(3)
Card()
Tag(22)
f()
Static數據的初始化(注意結合代碼調試理解):
package com.initialization.order;
class Bowl {
Bowl(){
System.out.println("Bowl(9)");
}
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
static Bowl b6 = new Bowl(6);
static Bowl b9 = new Bowl();
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}class Table {
static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
b2.f(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl b2 = new Bowl(2);
}
class Cupboard {
Bowl b3 = new Bowl(3);
Bowl b10 = new Bowl();
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl b5 = new Bowl(5);
}public class StaticInitialization {
//static Bowl b7 = new Bowl(7); //----------(1)
public static void main(String[] args) {
System.out.println(
"Creating new Cupboard() in main");
new Cupboard();
System.out.println(
"Creating new Cupboard() in main");
new Cupboard();
//t2.f2(1); //--------------(2)
//t3.f3(1); //---------------(3)
}
//static Bowl b8 = new Bowl(8); //----------------(4)
//static Table t2 = new Table(); //----------------(5)
//static Cupboard t3 = new Cupboard(); //---------(6)
} ///:~
調試以上代碼,總結出以下結論:
一、初始化的過程:總體來說順序為:static初始化->非static初始化->執行構造函數;
二、代碼分析一:對現有代碼執行結果如下:
Creating new Cupboard() in main
Bowl(6)
Bowl(9)
Bowl(4)
Bowl(5)
Bowl(3)
Bowl(9)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Bowl(9)
Cupboard()
f(2)
執行過程:
1、java解釋器尋找public class類,加載StaticInitialization 類;
2、尋找StaticInitialization 類中的static定義代碼段;這里因為(1)、(4)、(5)、(6)均加了注釋,所以StaticInitialization 中沒有static需要初始化;3、進入main函數中執行代碼輸出Creating new Cupboard() in main;
4、繼續執行new Cupboard();,注意初始化的順序是static初始化->非static初始化->執行構造函數;所以加載類Cupboard后,首先尋找Cupboard類中的static代碼段;
發現static段是: static Bowl b4 = new Bowl(4); static Bowl b5 = new Bowl(5);
同時發現有非static段是: Bowl b3 = new Bowl(3); Bowl b10 = new Bowl();
按順序先執行:static Bowl b4 = new Bowl(4); 初始化,因為定義的是Bowl類的實例,所以先加載Bowl類,進入Bowl類發現又有static代碼段static Bowl b6 = new Bowl(6);
static Bowl b9 = new Bowl();然而我們知道初始化static Bowl b4 = new Bowl(4); 需要調用Bowl 的構造函數,但調用構造函數之前必須將該類需要初始化的部分先進行初始化,所以執行到這里就要先進行Bowl類中的static代碼段的初始化,之后才能調用構造函數Bowl(int marker) 為static Bowl b4 = new Bowl(4); 進行初始化。于是b6,b9分別調用構造函數Bowl(int marker),Bowl(),輸出Bowl(6),Bowl(9),完了之后,b4調用構造函數Bowl(int marker)輸出Bowl(4),b4初始化結束,返回Cupboard類繼續執行,初始化b5,輸出Bowl(5),此時Cupboard類中static部分初始化完,接下來對非static部分初始化,即對b3和b10初始化,一樣的方法,加載Bowl類,發現static字段在上面已經初始化,所以這里直接調用Bowl類的構造函數,輸出Bowl(3),Bowl(9)。至此Cupboard類中需要初始化的部分已經初始化完了,所以放心大膽的調用Cupboard類的構造函數,為main函數中代碼完成new Cupboard();的實現,輸出Cupboard(),f(2)。程序執行返回到main函數,輸出:Creating new Cupboard() in main,代碼new Cupboard();又一次出現,這里實際上是想演示static只會初始化一次,而非static只要創建了對象或調用了成員、成員函數,會進行第二次初始化,于是可以看到輸出結果并沒有再輸出Bowl(6)、Bowl(9)、Bowl(4)、Bowl(5),而是輸出:Bowl(3)、Bowl(9)、Cupboard()、f(2)。
5、取消注釋(1)、(4),發現結果如下:
Bowl(6)
Bowl(9)
Bowl(7)
Bowl(8)
Creating new Cupboard() in main
Bowl(4)
Bowl(5)
Bowl(3)
Bowl(9)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Bowl(9)
Cupboard()
f(2)
可以看出輸出了Bowl(7)、Bowl(8),這說明在main()函數執行之前,程序要先對StaticInitialization進行檢查,如果有static部分,則先初始化。
6、再取消注釋(2)、(5)輸出結果為:
Bowl(6)
Bowl(9)
Bowl(7)
Bowl(8)
Bowl(1)
Bowl(2)
Table()
f(1)
Creating new Cupboard() in main
Bowl(4)
Bowl(5)
Bowl(3)
Bowl(9)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Bowl(9)
Cupboard()
f(2)
f2(1)
在前面的基礎上又輸出了Bowl(1)、Bowl(2)、Table()、f(1)。然而我們看到當沒有代碼
static Table t2 = new Table();的時候Table類中的static部分沒有被初始化,這說明什么?
static初始化只有在必要的時候才會進行。只有在創建了第一個Table對象之后才會進行初始化。總結如下:初始化順序為:加載public StaticInitialization類->初始化static->加載類Cupboard->初始化static->加載類Bowl->初始化static->執行Bowl類構造函數->初始化Cupboard類非static->調用Bowl類構造函數執行->調用Cupboard類構造函數執行->返回StaticInitialization類.