Is the code you posted copied and pasted?
If so I see 2 compile time issues:
Both classes are public and a file can only have a single public class
The package statement must be the first line in the file.
I'm not sure why the book claims the program runs, if above is accurate to the example in the book
posted 3 years ago
I do not think there are 2 compile time issues.
Knute Snortum worte:
The trick is that length in class Rope is static. That means there is only one copy per class. So rope1 and rope2 point to the same value in Rope.
This explanation seems to be understandable; the book provides the following explanation: The are two details to notice in this code. First, note that RopeSwing has an instance initializer and not a static initializer. Since RopeSwing is never constructed, the instance initializer does not run. The other detail is that length is static. Changes from one object update this common static variable.
I do not understand properly that RopeSwing has an instance initializer and not a static initializer. Thus RopeSwing is never constructed.
Urs Waefler wrote:I do not understand properly that RopeSwing has an instance initializer...
It's lines 6-8 of the code in your original post.
and not a static initializer.
Well, it's hard for me to point at something which isn't there. So since you don't understand properly that there isn't a static initializer, how about if you tell us which lines of that code are, in your opinion, a static initializer?
posted 3 years ago
If I have understood you right, the following code is the instance initializer:
I think, the user does not provide any constructor. Hence Java implements a default constructor. In this case it looks like this:
There is no static initializer, that is obvious.
Since RopeSwing is never constructed, the instance initializer does not run. I do not understand this explanation.
I have removed all package, import statements - they aren't relevant here (assume they are there).
So you have 2 classes.
1. Class RopeSwing, which has instance initializer, it gets called only when instance of RopeSwing class is created - that never happens.
2. Class Rope, very primitive, but contains static variable, not instance, important.
Now, execution order goes like that:
 static variables or static initializers (in the order they appear in the class)
 instance fields or instance initializers (in the order they appear in the class)
As we know, in this particular case, the class, which contains main method never gets instantiated, it has only main method which is a starting point of application. So, class gets loaded (looking to the execution list above) static variables gets initialized first, hence 2 objects of Rope created.
Instance initializer never gets executed. Let's move on further.
In main method rope1.length gets initialized to 2 (it could be accessed directly via class name, via instance variable it just to confuse you), then it gets initialized to 8 and finally printed, which is 8.
You are mixing things up and making associations where there are none to be made.
Urs Waefler wrote:The following code belongs to the class RopeSwing:
It is never executed, because there is no instance. Correct?
Let me state it differently and hopefully, unambiguously. Since this block of code is not prefixed with the "static" keyword, this means that it is an instance initialization block. Since this block is in the RopeSwing class, it is an instance initializer for instances of RopeSwing. What that means is that whenever an instance of the RopeSwing class is created, this code will be executed as though it were a part of whatever constructor was invoked. Since the only constructors that ever get invoked in that code are constructors of the Rope class and NOT a constructor of the RopeSwing class, then this instance initialization block will never be executed.
What is about these two statements? I think there are two constructors. Why are the references marked as static?
There's nothing special about marking these variables static. The use of static here has nothing to do with the invocation of Rope() constructors or the execution of code in the instance initialization block (as already explained above). The static declaration merely makes the rope1 and rope2 variables class variables of the RopeSwing class, i.e., they do not "belong" to any particular instance of RopeSwing but instead are shared by all instances of RopeSwing, therefore they "belong" to the RopeSwing class itself (which again is why they are called class variables)
I think your confusion comes from thinking that there's a connection between the static declaration, the Rope() constructors, and that static instance initialization block. The connections you think exist actually do not exist. It's like thinking that just because you are wearing tennis shoes, you are going to be able to play the piano. Those two things are unrelated and there's no connection between them. These examples are purposely made this way to see if you actually know that. Real-world code would never look this way, at least code that is actually useful.
The best ideas are the crazy ones. If you have a crazy idea and it works, it's really valuable.—Kent Beck