2

I am going through the book "Thinking in Java" by Bruce Eckel, and I've come across a code snippet that I, more or less, understand, but want to modify. In effect, the purpose of the code is to show that class static variables are instantiated only once and before said class's constructor method is called.

Here is link to the book's code on repl.it (I added the comments): https://repl.it/Bhct/6, and I'll post it and its result below:

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()");
    }
}

Result

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

What I want to do is to edit the Cups() constructor function's log to include a counter that represents the order in which they are called, i.e.:

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

Please see my comments for how I assumed this could be done. Defining a static variable in main and incrementing it via calling counter++ doesn't work because an "" is expected. However, I thought I declared counter as an int earlier?

I've tried a few variations of this, like making the incrementation a method inside and outside main, but I haven't had luck.

What major Java concept am I missing here?

I apologize in advance for the wording of this question. Not entirely sure how to ask this question.

1
  • You can make an static class counter, or an static int (to print it, just cast it with String.valueOf(int value). Commented Jan 28, 2016 at 17:40

1 Answer 1

1

Your approach was right, but you have to make your counter static inside Cups:

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++;
    }
}

The reason is that all Cups instances share the same counter. If they had each one separate counter, it would be 1 for each instance of Cups. By making the counter static, all instances increment the same variable.


This was the faster solution. The is another way, which needs more changes in your code, but is actually more similar to your approach (as you intended):

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++;
 }

You need to reference the counter by Main.counter.

Sign up to request clarification or add additional context in comments.

3 Comments

Gotcha. Thanks! Correct me if I'm wrong, but, in JavaScript, I would have defined counter outside the scope of the Cups constructor function (in lieu of a class), but here I don't have to worry about scope, per se, because static variables are instantiated only once.
@Bathsheba This is right if one uses Threads. However, this class doesn't, so there is only the main thread. Or is class loading multithreaded in Java?
it appears static initialization occurs once per class loader stackoverflow.com/questions/878577/… . I'm not familiar with class loading, but here are some links I'll have to dig into later: dzone.com/articles/java-classloader-handling, docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.