This week's book giveaways are in the Refactoring and Agile forums.
We're giving away four copies each of Re-engineering Legacy Software and Docker in Action and have the authors on-line!
See this thread and this one for details.
Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

when static variables are initialized

 
Karen Liu
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
static variables are initialized to default values.
I am wondering when that happens.
when a class is loaded, static vars are created(allocated space),
then static initializers and initializations in declarations are executed.
At what point, the default values are given?
This leads to the problem of forward reference.

If default values are given when static vars are created, then when at line 1, j has value of 0. why compiler says it is illegal forward reference? At that point, j has been declared and has default value of 0.
Thanks
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At what point, the default values are given?

1. Loading
2. Linking
___2.1 Verification
___2.2 Preparation
_______initialize fields to default values
___2.3 Resolution of Symbolic References
3. Initializing
___invoke static initializers and initializers for static fields
1. Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.
2. Linking is the process of taking a class or interface and combining it into the runtime state of the Java virtual machine so that it can be executed.
Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary.
2.1 Verification ensures that the binary representation of a class or interface is structurally correct.
2.2 Preparation involves creating the static fields for the class or interface and initializing those fields to their standard default values. Preparation may occur at any time following creation but must be completed prior to initialization.
2.3 Resolution of symbolic references in the class or interface is an optional part of linking.
3. Initialization of a class or interface consists of executing the class or interface initialization method <clinit>.
Initialization of a class or interface consists of invoking its static initializers and the initializers for static fields declared in the class.
Java Virtual Machine Specification Chapter 5
Java Language Specification 12.2 - 12.4
[ February 01, 2004: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
why compiler says it is illegal forward reference?

Because the JLS told the compiler to do that. According to JLS 8.3.2.3,
The declaration of a member needs to appear 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:
1. The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
2. The usage is not on the left hand side of an assignment.
3. C is the innermost class or interface enclosing the usage.
A compile-time error occurs if any of the three requirements above are not met.
These restrictions are designed to catch, at compile time, circular or otherwise malformed initializations.
[ February 01, 2004: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am reading C++ for Java Programmers by Timothy Budd. The first chapter, Basic Philosophical Differences, describes the history and the contrasting goals and objectives of C++ and Java. This chapter might answer your question in a general way.
 
Karen Liu
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow, thank you Marlene!
Your explaination is awesome.
Would you please explain this a litter further exp with the second:
if a member is declared before it is used, it can be used any place right?
why 2 says not on the left hand side of an assignment

The declaration of a member needs to appear 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:
1. The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.
2. The usage is not on the left hand side of an assignment.
3. C is the innermost class or interface enclosing the usage.
A compile-time error occurs if any of the three requirements above are not met.

Thanks
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if a member is declared before it is used, it can be used any place right?

Yes.
Why 2 says not on the left hand side of an assignment

Here is an example to help us understand the JLS:

Now, let us analyze the logic of this sentence:
The declaration of a member needs to appear before it is used only if
2. The usage is not on the left hand side of an assignment.
static int x1 = y1;
Usage of y1 is NOT on the left-hand side of an assignment
Therefore, the declaration of y1 MUST appear before y1 is used
static int x2 = y2 = 2;
Usage of y2 IS on the left-hand side of an assignment.
Therefore, the declaration of y2 can appear either before y2 is used or after y2 is used.
----
The declaration of a member needs to appear before it is used only if
1. The usage occurs in an instance (respectively static) variable initializer or in an instance (respectively static) initializer.
2. The usage is not on the left hand side of an assignment.
static void m() { int z = y3; }
Usage of y3 is NOT on the left-hand side of an assignment.
But usage is in a method, not in an initializer.
Therefore, the declaration of y3 can appear either before y3 is used or after y3 is used.
[ February 01, 2004: Message edited by: Marlene Miller ]
 
Karen Liu
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. That is very clear.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Karen.
For completeness, I thought I should also have some examples with static initializer blocks.

The usage of y1 and y4 is NOT on the left side of an assignment.
The declarations must occur before the usage.
The usage of y2 and y5 IS on the left side of an assignment.
The declarations may occur before or after the usage.
The usage of y3 is NOT on the left side of an assignment.
Since the usage occurs in a method,
the declaration of y3 may occur before or after the usage.
[ February 01, 2004: Message edited by: Marlene Miller ]
 
neil walker
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,
I appreciate this is late to the thread but it's very relevant. I got this question on a mock exam and it is identical to the above and I got it wrong because I said it would be a forward declaration error in the same way as the above code. However it does work and produces the value 0. So, what is the difference?




and more to the point why are we potentially going to be given stupid questions like this that have no bearing on real life and the compiler will tell us if it's wrong or not ;)
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic