Author Topic:   A qstn to think....and answer
maha anna
bartender
posted March 10, 2000 07:48 AM             
Hello everybody,
I have formed this qstn which tests our knowledge about the initialization process of a class. Try this. This program compiles and runs fine.(Don't spend time in checking the syntax..). The qstn is What is printed when you compile and run this appln. with/without the comments in the class sub?
(Of course assuming you are given only a scratch paper and a pen.. ). Tell us who are all passed ..
regds
maha anna
interface inter {
static final int INTER_ONE = base.one();
}
class base {
static final int ONE = one();
static int one(){
System.out.println("base.one() called");
return 1;
}
}

class sub extends base implements inter{
static {
System.out.println("static block of sub called");
}
/*static int one(){
System.out.println("sub.one() called");
return 10;
}*/
}
class test {
static{
System.out.println("static block of test called");
}
public static void main(String[] args){
System.out.println(sub.one());
}
}

[This message has been edited by maha anna (edited March 10, 2000).]

Jane Rozen
ranch hand
posted March 10, 2000 01:34 PM             
Good question,anna, makes you think, but what is interface doing there?

maha anna
bartender
posted March 10, 2000 03:14 PM             
Jane, I put the interface part in this declaration
class sub extends base implements inter{//....}
in order to say that when a subclass extends a superclass, and also implements an interface, during initialization of the subclass, only all the superclasses above in the inheritance hirarchy are initialized not the interfaces(ans its superinterfaces).
regds
maha anna.

shan
unregistered
posted March 13, 2000 08:34 AM           
These are the outputs ..
I am not sure why bas.one() called is repeated twice
here?? Expalin please...

with comments
static block of test called
base.one() called
base.one() called
1

If the comment is removed??
static block of test called
base.one() called
static block of sub called
sub.one() called
10

maha anna
bartender
posted March 13, 2000 09:18 AM             
The sequence of operations done by JVM in this particular appln is as follows.
With the comments
1. when you run the appln using this command 'java test' from the command line of DOS window, JVM loads the test.class into its memory.
2. It does the initialization part of test.class. Here we have only 1 static floating block. So it prints "static block of test called"
3. Then it sees 'sub.one()' method has to be called. For this, it has to load class 'sub' into memory first in order to invoke this method 'one()'. It sees the class 'sub' extends class base. So the superclass 'base' has to be loaded into memory and initialized first. The JVM also sees that , the called method 'one()' is not of class 'sub'. It belongs to class 'base'. It is just inherited to sub from base. Then what's is the point in initializing sub? . So JVM decides to just initialize the 'base' class alone and call the method 'one()'.

After the decision is made,Now it has to load and initilize 'base'. So the static final int ONE has to be initialized first. For this , it is calling it's own one() method so it prints 'base.one() called' the 1st time. Then, sine we are calling this method again from the main() method, 2nd time 'base.one() called' is printed.
Without the comments
In this case the subclass hides the static method one().
So the JVM decides that the called method sub.one() from the main(..) does indeed call the subclass's one() method not the 'base' class's one() method. So It does all the process which I have explained in previous case above. Apart from that it loads class 'sub' also and calls the subclass's version of one() method whenever one() is called.

I hope this gives a fair view of what's happening.What I found interesting was, for the first case, since the one() method was inherited to sub from base, eventhough we call as 'sub.one()' from main(), JVM decides to load only base class and it doesn't load sub at all.

regds
maha anna

[This message has been edited by maha anna (edited March 13, 2000).]

Java2learner
greenhorn
posted March 13, 2000 10:10 AM         
Hi Maha,
In the second part, with the comments removed, it prints :
static block of test called
base.one() called ==>> why is this printed?
static block of sub called
sub.one() called
10

IMO, since the JVM sees that method one() is existing in sub class, it won't load the base class, right ? So how does the second line get printed ? What about the execution of final
static variable in the interface inter in both cases?

Thanks..

maha anna
bartender
posted March 13, 2000 11:09 AM             
No, the superclass will be called in both the cases since sub extends base. In the first case , the static method one() is base's static method which can refer to only it's own static members. So no point in initializing sub. But in second case the class 'sub' 'hides' it by again defining the one() method. So JVM has to init both 'base' and 'sub'.

The bottom line is this. When a static method is called on a class, ALL the classes upto which class actually defines that method WILL be initialized. JVM leaves the rest of the subclasses in that hirearchy.
I am sorry if I am still not clear to you. Please refer to this chapter Execution in JLS.
regds
maha anna

[This message has been edited by maha anna (edited March 13, 2000).]

Rolf Weasel
ranch hand
posted March 13, 2000 10:24 PM             
maha anna, it seems like some of these decisions could be made at compile time rather than run time since the static method call is bound at compile time.could u comment on this? i will check out the chapter in the JLS once i get time. seems like it'll be one helluva read!
thanks!

The Moose is strong in Maha Anna!

------------------
May the Moose be with you.

[This message has been edited by Rolf Weasel (edited March 13, 2000).]

maha anna
bartender
posted March 14, 2000 12:16 AM             
Any var/class/interface/method ref from a class is represented in a symbolic reference table. This table is prepared at compile time itself. But when JVM is requested to execute the class, it loads/links(verifies/prepares/resolves) the class. Loading loads the class file into memory. Linking does 3 jobs. 1. JVM verifies if the class file obeys the the semantic requirements of Java . 2.Then it prepares by allocating static storage. 3. Then it optionally resolves the symbolic references in this class. There are 2 types of implementation. a) static/laziest types. In static type, all the resolution are done at compile time itself and the executable file has a copy of all the libraries called. This is the kind followed in language 'C'. But Java uses the 'laziest' method. It resolves the symbolic ref as and when it is called.

Eventhough the decisions are made at compile time, these decisions are verified at run time by resolving the symbolic refs by checking if they obey certain rules. These allow the binary compatiblity of classes. There are some pre-defined rules for which the binary compatiblity is ok/not.

While doing the symbolic ref resolution, if the JVM finds out that the decisions made at compile time are violated, then it throws Error.(Ex. abstractMethodError/VerifyError/NoSuchFieldError etc)

So yes,the decisions are made at compile time and JVM certainly verifies at run time.
regds
maha anna

Rolf Weasel
ranch hand
posted March 14, 2000 10:58 AM             
thanks a lot, Maha Anna!

------------------
May the Moose be with you.

vivian
unregistered
posted March 16, 2000 03:07 PM           
when I run this using SUN JVM, it generates the same result as above. BUT when executing using VJ++, the result is:

with comment:
static block of test called
base.one() called
base.one() called
static block of sub called
sub.one() called
10

Any comments?
Vivian

maha anna
bartender
posted March 16, 2000 03:15 PM             
I can't comment on your feed back. Because I tested this with all Sun's tools. I also think that the SCJP2 Exam also related to Sun's VM and Sun's Java Compiler only. May be others can comment on this.
regds
maha anna

Tony Alicea
sheriff
posted March 16, 2000 04:22 PM             
Ha ha!

DOn't mention VJ++ in a forum like this one at the risk of... never mind!

|