• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

static block.......

 
Ranch Hand
Posts: 435
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

What will be the output when class Test is run:
Options:
1)It will print 'In Sub' and 'QBANK'
2)It will print "QBANK"
3)Depends on the implementation of the JVM
4)It will not even compile
5)None of the above
Answer : 2)It will print "QBANK"
I feel that when in the main Sub.Id is called it should first print "In Sub" and then "QBANK" i.e the 1) option.
Where am I wrong?
Sonir
 
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by sonir shah:

What will be the output when class Test is run:
Options:
1)It will print 'In Sub' and 'QBANK'
2)It will print "QBANK"
3)Depends on the implementation of the JVM
4)It will not even compile
5)None of the above
Answer : 2)It will print "QBANK"
I feel that when in the main Sub.Id is called it should first print "In Sub" and then "QBANK" i.e the 1) option.
Where am I wrong?
Sonir



At compile time, the compiler can create a static binding to the variable ID in the Super class. In the println() statement in main, the static member ID is referenced by a type name, not an instance variable. And so the compiler can look at the Sub class, and see that there is no such member named ID, and then look to the parent class, and see that in that class there is such a member, so that's the one it links to.
Basically, the class Sub does not need to be loaded by the classloader in order for the println() statement to find the right variable it needs to print. Since the Sub class doesn't get loaded, its static initializers are never called, and that's why you don't see the text "In sub" in your output.
If you had written your main like this:
public static void main(String[] args)
{
Sub mySub = new Sub();
System.out.println(mySub.ID);
}
you would see the output from the Sub class, because it is being instantiated, therefore the classloader must load that class, therefore the class's static initializers will run.
This is confusing, I know. Sorry for the confusing explanation.
Rob
 
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi sonir,
again, classes r not loaded when u access its "static" members. classes r loaded when u create an instance of it.
thats why the class B is not loaded and u get direct value of var inherited from A.
regards
maulin.
 
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rob,
That was an excellent explanation, which helped me too.
Thanks!
-Paul
 
Ranch Hand
Posts: 417
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
sonir, do this and it will be all clear.
in the main method of class Test replace the statment for System.out.println and write this statement Sub ss = new Sub();
that's it. there is no System.out.println statment but when you would run the java Test then outout will be
In Sub
ok, so we know that static block is run at the runtime.

Originally posted by sonir shah:

What will be the output when class Test is run:
Options:
1)It will print 'In Sub' and 'QBANK'
2)It will print "QBANK"
3)Depends on the implementation of the JVM
4)It will not even compile
5)None of the above
Answer : 2)It will print "QBANK"
I feel that when in the main Sub.Id is called it should first print "In Sub" and then "QBANK" i.e the 1) option.
Where am I wrong?
Sonir

 
mark stone
Ranch Hand
Posts: 417
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
mauline and rob,
i rewrote the code and thought about it. well it turns out that there is more to it.
like say instead we had another static string, say T="TTT" defined in the class Sub and from class Test we called this string via Sub.T
then the class Sub would be loaded. But when we called the String ID the class was not loaded because the string was inherited from Super. fine.
BUT here is my problem. The compiler or rather the JVM (???) would have to search and go through the class Sub to find that hey, this String is not in this class, is it in its Superclass and it finds it. So basically that's how it goes.
But in doing so, ie finding that this string does not belong with class Sub, the class will have to be loaded ? right ? and i guess this is what the question is asking....
i hope you guys got my point about the loading of the class by the jvm at run time. (is this sentence ok ??)

Originally posted by Maulin, Vasavada:
hi sonir,
again, classes r not loaded when u access its "static" members. classes r loaded when u create an instance of it.
thats why the class B is not loaded and u get direct value of var inherited from A.
regards
maulin.

 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The compiler knows, at compile time, in which class a particular declaration can be found. At compile time, the compiler looks at Sub, and since there is no definition for the member 'i', it then looks in the class Super, and finds it there; now it can write the bytecode for the println statement at compile time. There is no run-time checking necessary for this, because you are using static references. As you mentioned above, if you actually try to instantiate a class, and then reference the member 'i' via that class instance, then the *run time* system has to get the current value of i.
Rob
 
mark stone
Ranch Hand
Posts: 417
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rob:
if you add this code in the class Sub
static String T = "TTTT";

and in class Test System.out.println for Sub.T
and if you run java Test the output is
In Sub TTTT
so it did run the class Sub. why ? if the compiler knew and added in the bytecodes about the static String T, why did it run it ?
I am stuck here.

Originally posted by Rob Ross:
The compiler knows, at compile time, in which class a particular declaration can be found. At compile time, the compiler looks at Sub, and since there is no definition for the member 'i', it then looks in the class Super, and finds it there; now it can write the bytecode for the println statement at compile time. There is no run-time checking necessary for this, because you are using static references. As you mentioned above, if you actually try to instantiate a class, and then reference the member 'i' via that class instance, then the *run time* system has to get the current value of i.
Rob


[ January 21, 2002: Message edited by: mark stone ]
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,
i tried the following code,

when we make line 1 and line 2 comment then Super is only loaded. but if we make it un-comment then Sub also gets loaded.
and , Mark, the super class code doesnt get copied to the subclass when we extend super class. so, even if the field is of super class refered by the subclass it need not load subclass as well if we want to access super class's field.
i am not still sure about compile time replacement of things. as if we put a statement like Super.n = "new name"; as a first statement of main() method then also we get correct output.
if compiler wants to optimize the code and replace/bind all static ref with values then it will have to really "RUN" the statement "Super.n = ..." which can't be done at compile time.
if it would have been final var then i would have agreed that compile time replacement is possible.
still i am not sure of things.
regards
maulin.
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think, the JVM loads the class only if the class is needed at runtime. So, as long as we dont have to do anything with Sub class directly, the JVM doesnt load it.
For eg:- if you add static block in Super similar to the one in Sub, the static block in Super displays the string.
So, the conclusion is, JVM loads the class only if a member is referenced.
 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I tried to run this excercise, however I always get the error that a non-ststic variable cannot be referenced from a static context. The variable in the super class is declared as static, exactly as in the first submission. Can anyone explain?
 
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Lubosh Bazant:
I tried to run this excercise, however I always get the error that a non-ststic variable cannot be referenced from a static context. The variable in the super class is declared as static, exactly as in the first submission. Can anyone explain?


try this with lot of other permu & combinations

 
reply
    Bookmark Topic Watch Topic
  • New Topic