About Question enthuware.ocajp.i.v7.2.1009 :
Moderator: admin
About Question enthuware.ocajp.i.v7.2.1009 :
ID is a static instance variable from Super. Should it be inherited?
-
- Site Admin
- Posts: 10325
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
There is nothing like a static instance variable. A member can be either a static member or an instance member. Not both.
Inheritance does not apply to static members.
HTH,
Paul.
Inheritance does not apply to static members.
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
Re: About Question enthuware.ocajp.i.v7.2.1009 :
First of all let me tell you that static members are those members which can be accessed directly without creating an object of that particular class, when static members of a class is used in some other class then it should be used by specifying the class name .(dot) static member's name(e.g. A.i in the following example), and also if any subclass class is getting inherited from a super class which has static members and if both subclass and super class are in the same package then that static members can be accessed from the base class without even using the class name of the super class.
-
- Posts: 53
- Joined: Thu Nov 22, 2012 12:01 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
To be frank, I don't fully understand the explanation given. I already knew it should print out QBANK, but not sure if the static block defined in Sub class is executed when the main method is using Sub.ID. According to the answer, it isn't executed actually. So I guess that static block in Sub is only executed when a Sub object is being instantiated, right?
-
- Site Admin
- Posts: 10325
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Not completely, what it means is that the Sub's static blocks are not executed until you access something that belongs to Sub class itself. In this case, ID actually belongs to Super, so there is no need to load class Sub. But if you had something like static int SUB_ID defined in Sub, and then if you access Sub.SUB_ID, the static block of Sub will be executed.icepeanuts wrote:To be frank, I don't fully understand the explanation given. I already knew it should print out QBANK, but not sure if the static block defined in Sub class is executed when the main method is using Sub.ID. According to the answer, it isn't executed actually. So I guess that static block in Sub is only executed when a Sub object is being instantiated, right?
So the issue is not about object creation (because we are talking about static stuff not instance stuff) but about when is that class actually required to be loaded.
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
-
- Posts: 53
- Joined: Thu Nov 22, 2012 12:01 am
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
much better explanation. Thank you, Paul.
-
- Posts: 27
- Joined: Thu Feb 07, 2013 9:46 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
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?
public static void main(String[] args){
System.out.println(Sub.ID);
}
it prints In SubQBANK, why so?
-
- Site Admin
- Posts: 10325
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Because to run the main method, the JVM needs to load Sub class, thereby causing Sub's static initializer to be executed, which prints In Sub.
Last edited by admin on Thu Oct 22, 2015 8:54 pm, edited 1 time in total.
Reason: Corrected explanation later.
Reason: Corrected explanation later.
If you like our products and services, please help us by posting your review here.
-
- Posts: 18
- Joined: Fri May 31, 2013 1:18 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
I don't understand what you mean by this.admin wrote:(...)
Inheritance does not apply to static members.
HTH,
Paul.
Java Tutorial from Oracle seems to claim otherwise:
A subclass inherits all the members (fields, methods, and nested classes) from its superclass.
http://docs.oracle.com/javase/tutorial/ ... asses.html
-
- Site Admin
- Posts: 10325
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
If you like our products and services, please help us by posting your review here.
-
- Posts: 18
- Joined: Fri May 31, 2013 1:18 pm
- Contact:
Re: About Question enthuware.ocajp.i.v7.2.1009 :
Thank you. This is a real brainer to me.
-
- 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?
-
- Site Admin
- Posts: 10325
- 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
-
- Site Admin
- Posts: 10325
- 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?
-
- Site Admin
- Posts: 10325
- 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?
-
- Site Admin
- Posts: 10325
- 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
-
- Site Admin
- Posts: 10325
- 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!
}
-
- Site Admin
- Posts: 10325
- 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.
Who is online
Users browsing this forum: No registered users and 10 guests