2016-01-28 39 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

相关问题