my dog learned polymorphism*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes 11 K&B questions. Question 3 Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "11 K&B questions. Question 3" Watch "11 K&B questions. Question 3" New topic
Author

11 K&B questions. Question 3

Joan Pujol
Ranch Hand

Joined: Oct 12, 2005
Posts: 54
I know that static blocks are initialized at class loading time. But my doubt is, when a class is loaded?
It's loaded the first time that appears in the source code?
For example, in the question, the class Raptor is loaded when it appears in the extends of Hawk?

PD: I know that the ClassLoader don't work with source code, but the rule can be used to know when a class is loaded?


The question is:
class Bird {
{ System.out.print("b1 "); }
public Bird() { System.out.print("b2 "); }
}
class Raptor extends Bird {
static { System.out.print("r1 "); }
public Raptor() { System.out.print("r2 "); }
{ System.out.print("r3 "); }
static { System.out.print("r4 "); }
}
class Hawk extends Raptor {
public static void main(String[] args) {
System.out.print("pre ");
new Hawk();
System.out.println("hawk ");
}
}

What is the result?

A). pre b1 b2 r3 r2 hawk
B). pre b2 b1 r2 r3 hawk
C). pre b2 b1 r2 r3 hawk r1 r4
D). r1 r4 pre b1 b2 r3 r2 hawk
E). r1 r4 pre b2 b1 r2 r3 hawk
F). pre r1 r4 b1 b2 r3 r2 hawk
G). pre r1 r4 b2 b1 r2 r3 hawk
H). The order of output cannot be predicted
I). Compilation fails

CORRECT: D

Question copyrighted Kathy sierra & Bert Bates
Akshay Kiran
Ranch Hand

Joined: Aug 18, 2005
Posts: 220

12.4 Initialization of Classes and Interfaces
Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class. Initialization of an interface consists of executing the initializers for fields (constants) declared there.
Before a class is initialized, its superclass must be initialized, but interfaces implemented by the class are not initialized. Similarly, the superinterfaces of an interface are not initialized before the interface is initialized.


12.4.1 When Initialization Occurs
Initialization of a class consists of executing its static initializers and the initializers for static fields declared in the class. Initialization of an interface consists of executing the initializers for fields declared in the interface.
Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class need not be initialized. Similarly, the superinterfaces of an interface need not be initialized before the interface is initialized.

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:


T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the reference to the field is not a compile-time constant (�15.28). References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.
The intent here is that a class or interface type has a set of initializers that put it in a consistent state, and that this state is the first state that is observed by other classes. 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 (�8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.

As shown in an example in �8.3.2.3, the fact that initialization code is unrestricted allows examples to be constructed where the value of a class variable can be observed when it still has its initial default value, before its initializing expression is evaluated, but such examples are rare in practice. (Such examples can also be constructed for instance variable initialization; see the example at the end of �12.5). The full power of the language is available in these initializers; programmers must exercise some care. This power places an extra burden on code generators, but this burden would arise in any case because the language is concurrent (�12.4.3).

Before a class is initialized, its superclasses are initialized, if they have not previously been initialized.

Thus, the test program:


class Super {
static { System.out.print("Super "); }
}
class One {
static { System.out.print("One "); }
}
class Two extends Super {
static { System.out.print("Two "); }
}
class Test {
public static void main(String[] args) {
One o = null;
Two t = new Two();
System.out.println((Object)o == (Object)t);
}
}

prints:

Super Two false

The class One is never initialized, because it not used actively and therefore is never linked to. The class Two is initialized only after its superclass Super has been initialized.
A reference to a class field causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

The test program:


class Super { static int taxi = 1729; }
class Sub extends Super {
static { System.out.print("Sub "); }
}
class Test {
public static void main(String[] args) {
System.out.println(Sub.taxi);
}
}

prints only:

1729

because the class Sub is never initialized; the reference to Sub.taxi is a reference to a field actually declared in class Super and does not trigger initialization of the class Sub.
Initialization of an interface does not, of itself, cause initialization of any of its superinterfaces.

Thus, the test program:


interface I {
int i = 1, ii = Test.out("ii", 2);
}
interface J extends I {
int j = Test.out("j", 3), jj = Test.out("jj", 4);
}
interface K extends J {
int k = Test.out("k", 5);
}
class Test {
public static void main(String[] args) {
System.out.println(J.i);
System.out.println(K.j);
}
static int out(String s, int i) {
System.out.println(s + "=" + i);
return i;
}
}

produces the output:

1
j=3
jj=4
3


The reference to J.i is to a field that is a compile-time constant; therefore, it does not cause I to be initialized. The reference to K.j is a reference to a field actually declared in interface J that is not a compile-time constant; this causes initialization of the fields of interface J, but not those of its superinterface I, nor those of interface K. Despite the fact that the name K is used to refer to field j of interface J, interface K is not initialized.
from the java language specification.
If you're preparing for the SCJP, I suggest strongly that you keep this book handy, it is freely avaiable for download at java.sun.com

for the online manual>>
http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html

for the downloadable html>>
http://java.sun.com/docs/books/jls/third_edition/download/langspec-3.0.zip

for the downloadable pdf>>
http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf

I prefer you download the html, it is much easier to browse and use, also it is a smaller file than the pdf.


"It's not enough that we do our best; sometimes we have to do<br />what's required."<br /> <br />-- Sir Winston Churchill
Joan Pujol
Ranch Hand

Joined: Oct 12, 2005
Posts: 54
A lot of thanks Akshay Kiran,

But uff, a lot of rules. Anyone knows easier rules, or an easy way to remember the rules for the exam purpouses?
[ October 23, 2005: Message edited by: Joan Pujol ]
Akshay Kiran
Ranch Hand

Joined: Aug 18, 2005
Posts: 220
so many???
there are just these

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:


T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the reference to the field is not a compile-time constant

the rest is just explanation, you will have to read it atleast once to understand, and then you can use these four rules.
Joan Pujol
Ranch Hand

Joined: Oct 12, 2005
Posts: 54
Excusme Akshay. Yesterday I had been studying a lot of time and I was a little tired and I was able to read your text with calm.

A lot of thanks for your patience. Now I understand well the rules
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: 11 K&B questions. Question 3