rahul_mkar,
for your first request -----------------------------
static init is done first (when the class is loaded into memory itself), then comes the instance init (done when an object is created from this class).
For example when you access a class's static method, the class is loaded into memory and so ONLY the static floatin blocks, static (class) vars are initialized an written in the same order in the source file. NO instance init done.
At the same time when you do new ThisClass() then if the class is not already in memory, then it is loaded and both static and instance inits are done. Otherwise if it was already loaded before then only the instance init are done and the correcponding constructor is called.
So in your code the static var i is initilized first and then z is initialized. I wrote this sample prog. for you. Play with this. It WILL DEFINITELY make you think./confuse/....clear at the end

************************************************************
output
stat block test1 called
------0
stat block test2 called
------10
stat block test3 called
instance block test1 called
Constructor test1() called
instance block test2 called
Constructor test2() called
instance block test3 called
Constructor test3() called
<pre>
class test1 {
static int stat11 =10;
static {
System.out.println("stat block test1 called");
}
int inst11 =20;
{
System.out.println("instance block test1 called");
}
test1() {
System.out.println("Constructor test1() called");
}
}
class test2 extends test1 {
static int stat21 =10;
static {
System.out.println("------"+test3.stat31);
System.out.println("stat block test2 called");
}
int inst21 =20;
{
System.out.println("instance block test2 called");
}
test2() {
System.out.println("Constructor test2() called");
}
public static void main(String[] args) {
new test2();
}
}
class test3 extends test2 {
static int stat31 =10;
static {
System.out.println("------"+test3.stat31);
System.out.println("stat block test3 called");
}
int inst31 =30;
{
System.out.println("instance block test3 called");
}
test3() {
System.out.println("Constructor test3() called");
}
public static void main(String[] args) {
new test3();
}
}
</pre>
*********************************************************
ORDER OF EXECUTION 1. - static initialization for test1 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)
2. - static initialization for test2 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)
3. - static initialization for test3 done...
(init occurs in the same order as written in source.Both static vars and static blocks are initialized)
4. - instance initialization for test1 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
5. - Constructor test1() called
6. - instance initialization for test2 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
7. - Constructor test2() called
8. - instance initialization for test3 done...
(init occurs in the same order as written in source.Both instance vars and instance blocks are initialized )
9. - Constructor test3() called
*********************************************************
for your 2nd request --------------------------
At compile time you can't refer to a var as such if it not known before this referencing. THis is the rule. Because the var is not yet known. But when you call a fn what the compiler actually it basically creates code to which implementaion of the fn to execute like that. At run time when you call a method, and if it refers to a class/instance var, if it is not yet initialized , the default values are taken for granted. The important point to note here is eventhough the class/instance var are given default valuse you can't forward reference through the ref as such.
Because the scope of a var and a method is differnet. A var's scope is at the place where it is declared and below the declaration point. But a method's scope is anywhere in the containing class. THis is the difference And also this is the reason why your programs behaves differently. Eventhough the link which I given below doesn't explicity elaborate this, we have link what is said in the 'scope' section and this context and come to a conclusion/reason.
regds
maha anna
From JLS <pre>
The static initializers and class variable initializers are executed in textual order and may not
refer to class variables declared in the class whose declarations appear textually after the use,
even though these class variables are in scope. This restriction is designed to catch, at
compile time, circular or otherwise malformed initializations. Thus, both:
class Z {
static int i = j + 2;
static int j = 4;
}
and:
class Z {
static { i = j + 2; }
static int i, j;
static { j = 4; }
}
result in compile-time errors.
Accesses to class variables by methods are not checked in this way class Z {
static int peek() { return j; }
static int i = peek();
static int j = 1;
}
class
Test {
public static void main(String[] args) {
System.out.println(Z.i);
}
}
produces the output:
0
</pre>
Please refer to JLS
especially this section regds
maha anna
[This message has been edited by maha anna (edited May 14, 2000).]