請看下面代碼,無法通過編譯,問題出在那?
package demo;
public class Test {
public static void main(String[] args){
Foo obj1=new Foo();
}
}
class Foo( ){
int value;
public Foo(int initValue){
value=initValue;
}
}
你可以得到什么結論?
結論:如果類提供一個自定義的方法,系統將不再提供默認方法。
JAVA字段初始化規律:
如果一個類中既有初始化塊,又有構造方法,同時還設定了字段的初始值,誰說了算?
package demo;
class InitializeBlockClass {
{
field=200;
}
public int field=100;
public InitializeBlockClass(int value){
this.field=value;
}
public InitializeBlockClass(){
}
}
結論:
這是一個生造出來展示Java語法特性的示例類,在實際開發中不要這樣寫代碼,應該盡量保證一個字段只初始化一次!
用上面的類,思考輸出的結果:
public static void main(String[]args){
InitializeBlockClass obj=new InitializeBlockClass();
System.out.println(obj.field);
obj=new InitializeBlockClass(300);
System.out.println(obj.field);
}
結論:
(類字段的初始化順序) 執行類成員定義時指定的默認值或類的初始化塊,到底執行哪一個要看哪一個“排在前面”。 執行類的構造函數。 類的初始化塊不接收任何的參數,而且只要一創建類的對象,它們就會被執行。因此,適合於封裝那些“對象創建時必須執行的代碼”。
請運行TestStaticInitializeBlock.java示例,觀察輸出結果,總結出“靜態初始化塊的執行順序”。
class Root
{
static{
System.out.println("Root的靜態初始化塊");
}
{
System.out.println("Root的普通初始化塊");
}
public Root()
{
System.out.println("Root的無參數的構造器");
}
}
class Mid extends Root
{
static{
System.out.println("Mid的靜態初始化塊");
}
{
System.out.println("Mid的普通初始化塊");
}
public Mid()
{
System.out.println("Mid的無參數的構造器");
}
public Mid(String msg)
{
//通過this調用同一類中重載的構造器
this();
System.out.println("Mid的帶參數構造器,其參數值:" + msg);
}
}
class Leaf extends Mid
{
static{
System.out.println("Leaf的靜態初始化塊");
}
{
System.out.println("Leaf的普通初始化塊");
}
public Leaf()
{
//通過super調用父類中有一個字符串參數的構造器
super("Java初始化順序演示");
System.out.println("執行Leaf的構造器");
}
}
public class TestStaticInitializeBlock
{
public static void main(String[] args)
{
new Leaf();
}
}
程序運行輸出結果: Root的靜態初始化塊 Mid的靜態初始化塊 Leaf的靜態初始化塊 Root的普通初始化塊 Root的無參數的構造器 Mid的普通初始化塊 Mid的無參數的構造器 Mid的帶參數構造器,其參數值:Java初始化順序演示 Leaf的普通初始化塊 執行Leaf的構造器
靜態初始化執行規律: 靜態初始化塊只執行一次。 創建子類型的對象時,也會導致父類型的靜態初始化塊的執行。
