2014-01-12 92 views
1

這可能是一個「重複」,但我不知道如何尋找這個問題...Java的非靜態成員變量初始化

我在聲明中初始化非靜態成員變量行:

public class A 
{ 
    private B b = new B(); 
    ... 
} 

我這樣做,而不是初始化的默認構造函數內部的變量:

public class A 
{ 
    private B b; 
    public A() 
    { 
     b = new B(); 
    } 
    ... 
} 

這兩者之間是否有區別,除了(可能)前者不是「ANSI Java」或類似的東西?

我得到了兩個不同的字節碼(即兩個不同的'class'文件),這導致我相信可能存在運行時差異。

所以我想知道在運行期間我是否有任何理由期待有什麼不同。

謝謝

回答

1

這種方法有一個小的區別!

當在構造函數中聲明變量時,有可能在一段時間後創建第二個構造函數,並且該變量將被初始化。爲了打擊這一聲明這個變量作爲最後的 - 這是可能的,當然;)

其他分歧不存在:)

public class A 
{ 
    private B b; 
    public A() { 
     b = new B(); 
    } 
    public A(int value) { // second constructor 
    } 
    ... 
} 

使用A a = new A(5);bnull後。

+0

「會創建第二個構造函數」?這到底是什麼意思呢? –

+0

@barakmanos樣本附 – MariuszS

3

第一個是同時聲明和初始化。

在第二個例子,而不是你有b變量的聲明中,你初始化變量構造函數沒有初始化,然後...

的功能上的差異可以來在您添加另一個構造的時刻,在這種情況下,即使在該構造函數中,b變量也應該被初始化,否則將會有很大的差異。

在你有變量,不管你有多少構造函數初始化實施首例...

老實說,我不明白你怎麼能假裝有相同的字節碼,寫兩個不同的東西,作爲這個案例 。

+0

但這是一個非靜態成員變量。當我創建一個'A'的實例時,這個變量將在構造函數內部或外部被初始化。也許你的意思是差異在於操作的順序?初始化第一個變量'b',然後調用方法'A()',反之亦然? –

1

沒有什麼不同(一般來說,聲明外部和內部的構造函數會表現不同的東西)。只是提醒一下,初始化外面會先運行,然後再進入一些特定的構造函數。例如:

class A { 
    int a = 3; 
    public A() { 
    a = 4; // now a = 4. not 3 
    } 
} 

但是,我經常用他們不同的目的:

  1. 初始化內部構造變量使其更清晰,並幫助您初始化更復雜的東西。例如,放置一些邏輯代碼,放置一個循環來添加項目,......在構造函數作用域之外進行初始化時,您無法做到這一點。

  2. 當你有很多重載構造函數時,有些變量總是聲明相同的。簡單的「狀態變量」,如isExistisEmpty ...我經常在構造函數作用域之外初始化。所以,所有其他的構造函數都不會做同樣的事情。

1

沒有區別,兩個代碼都很好。我個人更喜歡大班的第二種方式,同時第一種方式更喜歡小班授課。

0

的主要差別是函數的順序調用:

  • 在第一情況下,方法B()方法A()之前被調用。
  • 在第二種情況下,在方法B()之前調用方法A()

另外一個區別是什麼已建議在所有其他的答案...

時不會初始化變量b非默認構造函數存在:

  • 在第1如果使用該構造函數,變量b將被初始化爲,甚至
  • 在第二種情況下,變量b而不是在使用該構造函數時被初始化。