2016-01-28 38 views
2

我正在閱讀Bruce Eckel編寫的「Thinking in Java」一書,並且我遇到了一個代碼片斷,我或多或少都能理解,但想要修改。實際上,代碼的目的是顯示類靜態變量僅在調用所述類的構造函數方法之前實例化一次。是否可以將參數傳遞給Java構造方法?如果是這樣,這是一個好習慣嗎?

這裏是鏈接到本書的上repl.it 代碼(我加的註釋)https://repl.it/Bhct/6,我會後和低於其結果是:

class Main { 
    public static void main(String[] args) { 
     System.out.println("Inside main()"); 
     Cups.c1.f(99); 
    } 

    // Want to initialize a counter int here 
    // static int counter = 1; 

    // Want to pass counter to Cups constructor here: 
    // static Cups x = new Cups(counter); 
    static Cups x = new Cups(); 
    // counter++; 
    // static Cups x = new Cups(counter); 
    static Cups y = new Cups(); 
    // counter++; 
    // static Cups x = new Cups(counter); 
    static Cups z = new Cups(); 
} 

class Cup { 
    Cup(int marker) { 
     System.out.println("Cup("+ marker +")"); 
    } 
    void f(int marker) { 
     System.out.println("f(" + marker + ")"); 
    } 
} 

class Cups { 
    int counter = 1; 
    static Cup c1; 
    static Cup c2; 
    static { 
     c1 = new Cup(1); 
     c2 = new Cup(2); 
    } 
    // Want to pass an arg to Cups() like this: 
    // Cups(int counter) { 
    //  System.out.println("Cups() constructor #" + counter); 
    // } 
    Cups() { 
     System.out.println("Cups()"); 
    } 
} 

結果

Cup(1) 
Cup(2) 
Cups() 
Cups() 
Cups() 
Inside main() 
f(99) 

我想要做的是編輯Cups()構造函數的日誌,以包含一個表示它們被調用順序的計數器,即:

Cup(1) 
Cup(2) 
Cups() 1 
Cups() 2 
Cups() 3 
Inside main() 
f(99) 

請參閱我的意見,我如何認爲這可以完成。在main中定義靜態變量並通過調用counter++對其進行增量操作不起作用,因爲預計會出現「」。但是,我以爲我早些時候宣佈計數器爲int?

我已經嘗試了一些這樣的變化,就像在主內部和外部增加一個方法,但我沒有運氣。

我在這裏錯過了什麼主要的Java概念?

對於這個問題的措辭,我很抱歉。不完全確定如何提出這個問題。

+0

您可以創建一個靜態類計數器或一個靜態int(要打印它,只需將其與String.valueOf(int值)一起轉換。 – kunpapa

回答

1

你的做法是對的,但你必須讓你的櫃檯裏面靜杯:

class Cups { 
    static int counter = 1; 
    static Cup c1; 
    static Cup c2; 
    static { 
     c1 = new Cup(1); 
     c2 = new Cup(2); 
    } 

    Cups() { 
     System.out.println("Cups() constructor #" + counter); 
     counter++; 
    } 
} 

的原因是,所有的杯子實例共享相同的計數器。如果他們有每個一個單獨的計數器,那麼每個杯子實例將是1。通過使計數器爲靜態,所有實例都增加相同的變量。


這是更快的解決方案。該是另一種方式,它需要在你的代碼更多的變化,但實際上更類似於你的方法(如你意):

class Main { 
    public static void main(String[] args) { 
     System.out.println("Inside main()"); 
     Cups.c1.f(99); 
    } 

    static int counter = 1; 

    // Want to pass counter to Cups constructor here: 
    static Cups x = new Cups(counter); 

    // Want to increment that counter here 
    static Cups y = new Cups(counter); 

    // Want to increment that counter here 
    static Cups z = new Cups(counter); 

} 

Cups(int counter) { 
    System.out.println("Cups() constructor #" + counter); 
    Main.counter++; 
} 

您需要通過Main.counter引用的計數器。

+0

Gotcha。謝謝!糾正我,如果我錯了,但在JavaScript中,我會在Cups構造函數的範圍之外定義計數器(代替類),但是在這裏我不必擔心範圍本身,因爲靜態變量僅實例化一次。 – pward

+0

@Bathsheba這是對的如果使用'Thread's。但是,這個類沒有,所以只有主線程。或者是在Java中加載多線程的類? – exception1

+0

它看起來每個類加載器都會發生一次靜態初始化http://stackoverflow.com/問題/ 878577/are-java-static-initializers-thread-safe /#answer-878624。我對類加載不熟悉,但以下是一些鏈接,我將稍後再深入研究:https:// dzone。com/articles/java-classloader-handling,http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html – pward

相關問題