The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C. The usage is not on the left hand side of an assignment. The usage is via a simple name. C is the innermost class or interface enclosing the usage.
Jan Stückrath wrote:...but is there als an intuition why they defined it this way?
...execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
...execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class.
Joe Bishara wrote:In your code, the static initializer doesn't use the declared staticint field. It uses a copy of the declared staticint field.
Jan Stückrath wrote:Shouldn't the compiler generate this correct code...
Joe Bishara wrote:All we can do as developers is follow the rules specified in the JLS.
Jan Stückrath wrote:From my experience, "strange" behavior of a language is often caused by compatibility issues with other features or similar problem. In this case I could just not see the reason for the specification to be this way.
Joe Bishara wrote:
I don't see it as "strange" behaviour. The compiler is your friend. It will not catch every bug, but it will take every precaution to prevent what it perceives to be a potential bug.
Joe Bishara wrote:The compiler can only do so much.
![]()
@Nick
That was also the behaviour that confused me in the beginning, but it is clearly specified this way. For now I assume that they cosidered a less (or more) strict specification not worth the effort.
nick woodward wrote:...why is this:
allowed, but this is not:
Joe Bishara wrote:
nick woodward wrote:...why is this:
allowed, but this is not:
The initializers will be executed in the textual order in which they appear:
class initializers will be executed in the class initialization method (generated by the compiler) instance initializers will be executed in the constructors
Field declaration is a different thing. Before a field can be initialized, it must first be declared.
Joe Bishara wrote:In a class, declaration code is separate from initialization code:
all instance field initialization code exist in the constructor all instance field declaration code exist outside the constructor
When the compiler encounters an instance field declaration with initialization int x = 1, the compiler will move the instance field initialization code x = 1 (not the instance field declaration code int x) to the constructor. The compiler will also move instance initializers (aka instance initialization blocks) to the constructor. They will be moved to the constructor in the order in which they appear in the source code.
So this code
will look like this after compilation
When an instance of Test is created with the new keyword:
memory will be allocated to the object the JVM will initialize its fields to default values - at this point, the declaration int x has a value of 0 the JVM invoke the object’s constructor to initialize its fields - at this point, the declaration int x has a value of 1
nick woodward wrote:i'm assuming the initialization code is moved to the beginning of the constructor, right? (after super() which will already have been called)
nick woodward wrote:thanks for your help!
This guy is skipping without a rope. At least, that's what this tiny ad said:
The Low Tech Laboratory Movie Kickstarter is LIVE NOW!
https://www.kickstarter.com/projects/paulwheaton/low-tech
|