2014-05-13 48 views
4

下面有這個輸出。Java - 爲什麼重複調用方法被調用兩次(或者至少看起來是這樣)?

Hello World! 
main.ConstructedDerivedClass:6.0 
main.ConstructedDerivedClass:6.0 
public class ConstructedDerivedClass extends ConstructedBase { 

    private static final double version = 6.0; 

    public static void main(String[] args) { 

     System.out.println("Hello World!"); 

     ConstructedDerivedClass derivedClass = new ConstructedDerivedClass(); 
    } 

    public ConstructedDerivedClass() { 
     showMyAttributes(); 
    } 

    @Override 
    protected void showMyAttributes() { 
     System.out.println(this.getClass().getName() + ":" + version); 
    } 
} 

public class ConstructedBase { 

    private static final double version = 15.0; 

    public ConstructedBase() { 
     showMyAttributes(); 
    } 

    protected void showMyAttributes() { 
     System.out.println(this.getClass().getName() + ":" + version); 
    } 
} 

我希望它只是顯示一條線,該子類(ConstructedDerivedClass)。但相反,它打印出來兩次。我知道一般情況下,你應該避免從構造函數中調用overriden方法,但我想親自看看這是如何工作的。

實際上,我知道爲什麼版本在兩行上都是'6.0' - 因爲字段被聲明爲靜態,當然靜態字段是首先初始化的。但仍然不明白爲什麼兩條線。

任何指導,將不勝感激。

+0

這可能是一個重複的(但我沒有」但是即使是這樣,這是一個寫得很好的問題,它清楚地顯示了你感興趣的輸出,以及完整的代碼。做得好! –

+0

謝謝。這仍然是新的。這兩個答案在下面有幫助。很難挑選一個。 –

回答

5

這是因爲當你寫

public ConstructedDerivedClass() { 
    showMyAttributes(); 
} 

編譯器實際上放置在字節碼超級默認構造函數的調用所以它相當於

public ConstructedDerivedClass() { 
    super();   
    showMyAttributes(); 
} 
5

當實例化一個對象時,它會在運行其自己的構造函數之前調用其父類的超級構造函數。

你可以想像,有這一行總是以你的構造函數:

public MyClass() { 
    super(); //If this line is not here, it is implicit. 
    //rest of the code 
} 

您可以通過提供自己的explicit, any-args超級構造函數調用覆蓋此,但它必須是該方法的第一行。

public MyClass() { 
    super(1, "Hello Word", null); //written explicitly, no other super-constructor code will run 
    //rest of the code 
} 

當超類沒有定義無參數構造函數時,這會很有用。

+0

明白了。只挑選另一個,因爲我能夠清楚地看到'showAttributes()'是如何被調用兩次的。但是這也有幫助。 –

相關問題