2011-05-03 68 views
24

我準備了Java認證考試,我已經在實踐檢驗的一個見過這樣的代碼:爲什麼此Java代碼在方括號外的大括號({})中?

class Foo { 
    int x = 1; 
    public static void main(String [] args) { 
     int x = 2; 
     Foo f = new Foo(); 
     f.whatever(); 
    } 
    { x += x; } // <-- what's up with this? 
    void whatever() { 
     ++x; 
     System.out.println(x); 
    } 
} 

我的問題是......它是有效的寫在大括號中的代碼的方法外?這些(如果有的話)有什麼影響?

+2

參見[8.6實例初始值設定(http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 )。 – trashgod 2011-05-03 04:43:40

+0

斯蒂芬,它可能因爲話題而重複,但我以完全不同的方式得到了這個 – nairdaen 2011-05-03 04:52:02

+2

正如其他人所指出的那樣,這是有效的。然而,在你的生活中的某個時候,你會在獲得Java認證後進行編程。請不要在日常工作中使用這種結構。請。我討厭Java認證。它教會了你所有令人不安的錯綜複雜的,有時是微妙的方式來混淆你的同事和引入錯誤。 – rfeak 2011-05-03 05:17:20

回答

31

here借 -

通常情況下,你乾脆把代碼放在一個 構造函數初始化實例變量。有兩種方法可以使用構造函數來初始化實例變量:初始化塊和最終方法。 初始化語句塊實例變量看起來就像靜態初始化 塊,但沒有static關鍵字:

{ 
    // whatever code is needed for initialization goes here 
} 

Java編譯器副本初始化語句塊到每一個構造函數。因此,這種方法可以用來在多個構造函數之間共享一段代碼。

您可能還想看看討論here

+0

我有一個問題,爲什麼這個代碼從來沒有執行過... ... {} {System.out.println(「com.test.BaseClazz.initial」); } – Omer 2016-12-01 21:31:03

6

這是一個initializer block。它用於設置實例變量。在構造函數中使用初始化塊的動機是爲了防止編寫冗餘代碼。 Java編譯器將塊的內容複製到每個構造函數中。

8

這是一個初始化塊,在類的實例被加載/創建時執行,並用於初始化類的成員屬性(請參閱Java http://download.oracle.com/javase/tutorial/java/javaOO/initial.html)。您可以根據需要擁有儘可能多的塊,並且會從頂部到底部實例化。

除了實例塊之外,還可以根據需要使用盡可能多的靜態塊以及初始化靜態成員。他們將如下聲明:

public class Initialization { 

    static int b = 10; 

    int a = 5; 

    static { 
     b = -9; 
    } 

    { 
     a += 2; 
    } 

    public static void main(String[] args) throws Exception { 

     System.out.println(ClientVoting.b); 
     System.out.println(new ClientVoting().a); 
     System.out.println(ClientVoting.b); 
     System.out.println(new ClientVoting().a); 

    } 

    static { 
     b = 1; 
    } 

    { 
     a++; 
    } 
} 

雖然類正在初始化,靜態部件「b」被作爲10初始化,則第一個靜態範圍其值更改爲-9,後來爲1。這僅在類加載時執行一次。這在main方法的第一行初始化之前執行。

另一方面,與您的類相似的示例是實例引用「a」。 A初始化爲5,然後實例塊將其更新爲7,最後一個塊更新爲8.如預期的那樣,靜態成員僅在此代碼中初始化一次,而實例塊在每次創建新實例時執行。

輸出到本實施例中是1 8 1 8