Thank you. This is a real brainer to me.
About Question enthuware.ocajp.i.v7.2.1009 :
Moderator: admin
-
- Posts: 18
- Joined: Fri May 31, 2013 1:18 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
-
- Posts: 33
- Joined: Wed Nov 13, 2013 4:11 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Hi,
Still don't grasp this concept 100%... I have a slight variation on the question code:
Now if I uncomment the line 'static String IDe = "Querulant";' in class Sub,
'In SubQuerulant' will be printed. But if I comment it out I get a compile time error:' Uncompilable source code - Erroneous tree type: <any>
at LearnJava.LearnJava.main'
Looks like the static initializer block of class Sub is not executed when I refer to Sub.IDe. Why is this?
Still don't grasp this concept 100%... I have a slight variation on the question code:
Code: Select all
class Super {
static String ID = "QBANK";
}
class Sub extends Super{
//static String IDe = "Querulant";
static {
System.out.print("In Sub");
String IDe = "Querulant";
}
}
public class LearnJava{
public static void main(String[] args){
System.out.println(Sub.IDe);
}
}
'In SubQuerulant' will be printed. But if I comment it out I get a compile time error:' Uncompilable source code - Erroneous tree type: <any>
at LearnJava.LearnJava.main'
Looks like the static initializer block of class Sub is not executed when I refer to Sub.IDe. Why is this?
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
I don;t see how your code can print "In SubQuerulant". I see only "In Sub" in your code. Please paste exact code that you are using.
BTW, if you comment static String IDe = "Querulant"; why do you expect System.out.println(Sub.IDe); to compile??
-Paul.
BTW, if you comment static String IDe = "Querulant"; why do you expect System.out.println(Sub.IDe); to compile??
-Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 33
- Joined: Wed Nov 13, 2013 4:11 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
System.out.println(Sub.IDe); prints "In SubQuerulant": first the static initializer block in class Sub is executed, printing "in Sub", then the value of the static instance variable 'IDe' is printed giving resulting in "In SubQuerulant".admin wrote:I don;t see how your code can print "In SubQuerulant". I see only "In Sub" in your code. Please paste exact code that you are using.
I expect System.out.println(Sub.IDe); to give me the value for the static variable IDe when it is initialized in _the static initialiser block_ of Sub. As it is now, it is only printed (with the text "In Sub") when it is _not_ defined in a static initialiser block but outside.
Thanks
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
If you comment out static String IDe = "Querulant"; IDe will become undefined. So again, why would you expect System.out.println(Sub.IDe); to compile if IDe is not even defined?
If you like our products and services, please help us by posting your review here.
-
- Posts: 33
- Joined: Wed Nov 13, 2013 4:11 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
//why would you expect System.out.println(Sub.IDe); to compile if IDe is not even defined?
Because it is defined in the static initialiser block:
static {
System.out.print("In Sub");
String IDe = "Querulant";
}
Why doesn't this work when referring to the class?
Because it is defined in the static initialiser block:
static {
System.out.print("In Sub");
String IDe = "Querulant";
}
Why doesn't this work when referring to the class?
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Because variables defined within a static block do not belong to the class. Their scope is local to that static block.
You should check out http://docs.oracle.com/javase/specs/jls ... index.html for more details.
You should check out http://docs.oracle.com/javase/specs/jls ... index.html for more details.
If you like our products and services, please help us by posting your review here.
-
- Posts: 33
- Joined: Wed Nov 13, 2013 4:11 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Ah... thanks for putting that straight.
-
- Posts: 36
- Joined: Tue May 06, 2014 8:30 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
I am totally lost reading everyone's comment.
I don't understand how "QBANK" is printed much less compile since ID belongs to the class "Super" and is NOT inherited by the class "Sub". If it is not inherited by the class "Sub", how is it accessible by the class "Sub" using "Sub.ID".
Would someone please explain?
I don't understand how "QBANK" is printed much less compile since ID belongs to the class "Super" and is NOT inherited by the class "Sub". If it is not inherited by the class "Sub", how is it accessible by the class "Sub" using "Sub.ID".
Would someone please explain?
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
It is not inherited but Java language still allows base class's static members to be accessed using the name of a subclass. That is just how the language has been designed. There is no special reason.
HTH,
Paul.
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 3
- Joined: Tue Nov 26, 2013 11:03 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Hi Paul,
I have visited the oracle link that you have provided:
http://docs.oracle.com/javase/specs/jls ... ls-12.html
While browsing, I stumbled upon this example:
Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces
Everything's good, but shouldn't be included on the result (first line), ? just like how
Pretty confused on this, maybe I'm missing something really easy, would appreciate your help. Thanks
I have visited the oracle link that you have provided:
http://docs.oracle.com/javase/specs/jls ... ls-12.html
While browsing, I stumbled upon this example:
Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces
Code: Select all
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;
}
}
This program produces the output:
1
j=3
jj=4
3
Code: Select all
ii=2
has been included in the result when K.j is called.jj = 4
Pretty confused on this, maybe I'm missing something really easy, would appreciate your help. Thanks
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
They have given the explanation right below the code.
HTH,
Paul.
J's is defined directly as 1 (which makes it a compile time constant). While J's J is defined as Test.out("j", 3), which is a method call executed at run time. Therefore, J has to be initialized but I doesn't have to be initialized. That is why J.jj gets initialized but I.ii is not initialized.The reference to J.i is to a field that is a constant variable (§4.12.4); therefore, it does not cause I to be initialized (§13.4.9).
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 29
- Joined: Sun Apr 05, 2015 11:26 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Hi Paul,
I read what was written above regarding this question but I am not sure I fully understood.
According to the explanation given:
That is why the static block in Sub is not executed.
Thanks
I read what was written above regarding this question but I am not sure I fully understood.
According to the explanation given:
Here when we have:A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
...
-A static field declared by T is used and the field is not a constant variable (§4.12.4).
...
we actually refer to the ID that Sub inherits from Super. So there is no need to initialize Sub, right? We remain only at Super...System.out.println(Sub.ID);
That is why the static block in Sub is not executed.
Thanks
-
- Posts: 24
- Joined: Wed Sep 02, 2015 3:43 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Hello Paul, this is the most difficult question i've come across so far... I've tested some variations, and do not understand why QBANK is not printed in the following code. Thanks in advance, this is a real riddle to me!
class Super {
static String ID = "QBANK";
}
class Sub extends Super {
static String ID;
public Sub() { } //calls Super's default constructor. The Super class loads. By now, ID should already have the QBANK value!
static {
System.out.println("in sub");
}
}
public class Ape {
public static void main(String args[]) {
Sub s = new Sub();
System.out.println(Sub.ID); //why is null printed instead of QBANK? At this stage, ID should have the QBANK value!
}
class Super {
static String ID = "QBANK";
}
class Sub extends Super {
static String ID;
public Sub() { } //calls Super's default constructor. The Super class loads. By now, ID should already have the QBANK value!
static {
System.out.println("in sub");
}
}
public class Ape {
public static void main(String args[]) {
Sub s = new Sub();
System.out.println(Sub.ID); //why is null printed instead of QBANK? At this stage, ID should have the QBANK value!
}
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
This is not a big mystery. You have a static ID field in Super as well as in Sub. When you access Sub.ID, the compiler will resolve it to Sub's ID and that is null. If you print Super.ID, QBANK will be printed.
HTH,
Paul.
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 24
- Joined: Wed Sep 02, 2015 3:43 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Thank you very much Paul.
-
- Posts: 2
- Joined: Wed Oct 14, 2015 7:36 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
I know this was posted a long time ago.. but I just now stumbled upon this
So there was this question on 1st page of this thread:
First of all, as Sweetpin2 stated, he just copied code (main method) from class Test to class Sub so now we have 2 (equal) main methods in file (one in Sub and one in Test class). When we compile this file (e.g. run "javac Test.java" in cmd on Windows, in case file is saved as Test.java) we will get 3 .class files. Two of them (Sub.class and Test.class) have main methods.
Now, when we run main from Test (e.g. run "java test.Test" in cmd on Windows) we get "QBANK" as output. Just like answer of OCA question says.
But if we run main from Sub (e.g. run "java test.Sub" in cmd on Windows) we get "In SubQBANK" as output. And now.. this is what user Sweetpin2 noticed. But reason for this behavior is quite different, in my opinion.
The simplest explanation for this is that, when main method is executed in Sub class, that class gets loaded (instead of Test class, so "In Sub" gets printed) and only after that, Sub.ID is printed. In case method from Test class is run, class Sub is never loaded so "In Sub" is never printed. In both cases main method calls "System.out.println(Sub.ID);" so they are both refereing to class Sub but this has actually no effect on outcome in this case.
Note that this can easily can be tested in some IDE (like Eclipse) since IDE can automatically detect two main methods. When user asks IDE to run code as java Application it will ask user to specify main method to run (int this case: "Sub-test" and Test-test") and output will depend on user choice.
Sorry for long post.
And correct me if I am wrong
So there was this question on 1st page of this thread:
And admin response was:Sweetpin2 wrote:But When we put below code in Sub class itself
public static void main(String[] args){
System.out.println(Sub.ID);
}
it prints In SubQBANK, why so?
Well... I must say.. this answer may not be quite true.admin wrote:Because when you do Sub.ID, you are refering to the class Sub, and so Sub's static initialize is run, which prints "In Sub" and then QBANK is printed.
First of all, as Sweetpin2 stated, he just copied code (main method) from class Test to class Sub so now we have 2 (equal) main methods in file (one in Sub and one in Test class). When we compile this file (e.g. run "javac Test.java" in cmd on Windows, in case file is saved as Test.java) we will get 3 .class files. Two of them (Sub.class and Test.class) have main methods.
Now, when we run main from Test (e.g. run "java test.Test" in cmd on Windows) we get "QBANK" as output. Just like answer of OCA question says.
But if we run main from Sub (e.g. run "java test.Sub" in cmd on Windows) we get "In SubQBANK" as output. And now.. this is what user Sweetpin2 noticed. But reason for this behavior is quite different, in my opinion.
The simplest explanation for this is that, when main method is executed in Sub class, that class gets loaded (instead of Test class, so "In Sub" gets printed) and only after that, Sub.ID is printed. In case method from Test class is run, class Sub is never loaded so "In Sub" is never printed. In both cases main method calls "System.out.println(Sub.ID);" so they are both refereing to class Sub but this has actually no effect on outcome in this case.
Note that this can easily can be tested in some IDE (like Eclipse) since IDE can automatically detect two main methods. When user asks IDE to run code as java Application it will ask user to specify main method to run (int this case: "Sub-test" and Test-test") and output will depend on user choice.
Sorry for long post.
And correct me if I am wrong
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
You are right. I misunderstood what he was saying. Since the main method is in Sub, that class is loaded and because of that its static initializer is executed, which prints InSub.
Very sorry about the mistake and thanks for your feedback!
-Paul.
Very sorry about the mistake and thanks for your feedback!
-Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 7
- Joined: Wed Mar 23, 2016 1:39 am
- Contact:
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
That is indeed the correct option mentioned in the question as well.
Paul.
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 7
- Joined: Wed Mar 23, 2016 1:39 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
no the software mention QBANK as wrong answer
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Attached is what I see and this question hasn't been changed since 27 Nov 2013. Could you please check it again and confirm that you don't see option 2 as the correct answer?
Paul.
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 4
- Joined: Thu Jan 26, 2017 8:45 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
The java SE8 language specification is:
http://docs.oracle.com/javase/specs/jls ... l#jls-12.4
"A reference to a static field (§8.3.1.1) 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."
http://docs.oracle.com/javase/specs/jls ... l#jls-12.4
"A reference to a static field (§8.3.1.1) 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."
-
- Posts: 25
- Joined: Fri Aug 04, 2017 12:21 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
class Super { static String ID = "QBANK"; }
class Sub extends Super{
static {
ID="QB";
System.out.print("In Sub"); }
}
class test {
public static void main(String[] args) {
System.out.println(Sub.ID);
}
}
In the above code, ID is being initialized again by the subclass to another value. Isn't ignoring this initialization wrong ?
I mean here, in this case, this initialization will not even be considered !
class Sub extends Super{
static {
ID="QB";
System.out.print("In Sub"); }
}
class test {
public static void main(String[] args) {
System.out.println(Sub.ID);
}
}
In the above code, ID is being initialized again by the subclass to another value. Isn't ignoring this initialization wrong ?
I mean here, in this case, this initialization will not even be considered !
Online
-
- Site Admin
- Posts: 10055
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Not sure what you mean by, "isn't ignoring this initialization wrong".
If you like our products and services, please help us by posting your review here.
Who is online
Users browsing this forum: admin and 42 guests