Page 1 of 2

About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 11, 2012 8:44 pm
by ETS User
ID is a static instance variable from Super. Should it be inherited?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed Dec 12, 2012 6:19 am
by admin
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Fri Jan 18, 2013 2:50 pm
by Deepa
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Sun Jan 20, 2013 6:12 am
by icepeanuts
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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Sun Jan 20, 2013 7:37 am
by admin
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?
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.

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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Mon Jan 21, 2013 12:50 am
by icepeanuts
much better explanation. Thank you, Paul.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed Feb 27, 2013 11:41 pm
by Sweetpin2
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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Thu Feb 28, 2013 7:21 am
by admin
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Fri May 31, 2013 4:33 pm
by Crashtest
admin wrote:(...)
Inheritance does not apply to static members.
HTH,
Paul.
I don't understand what you mean by this.

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

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Fri May 31, 2013 5:09 pm
by admin

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Sat Jun 01, 2013 10:47 am
by Crashtest
Thank you. This is a real brainer to me.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 7:41 am
by javaman
Hi,
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);
   }
}
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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 7:51 am
by admin
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 8:28 am
by javaman
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.
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".
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

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 11:22 am
by admin
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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 11:25 am
by javaman
//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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 11:45 am
by admin
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Dec 10, 2013 5:55 pm
by javaman
Ah... thanks for putting that straight.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed May 07, 2014 3:02 pm
by vchhang
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?

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed May 07, 2014 7:56 pm
by admin
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.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed Aug 20, 2014 10:47 am
by lorraine
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

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
Everything's good, but shouldn't

Code: Select all

ii=2
be included on the result (first line), ? just like how
jj = 4
has been included in the result when K.j is called.
Pretty confused on this, maybe I'm missing something really easy, would appreciate your help. Thanks

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Wed Aug 20, 2014 8:47 pm
by admin
They have given the explanation right below the code.
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).
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.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Fri Jun 19, 2015 2:51 pm
by ElizabethCM
Hi Paul,

I read what was written above regarding this question but I am not sure I fully understood.
According to the explanation given:
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).
...
Here when we have:
System.out.println(Sub.ID);
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...
That is why the static block in Sub is not executed.

Thanks

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Oct 06, 2015 6:28 am
by heleneshaikh
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!
}

Re: About Question enthuware.ocajp.i.v7.2.1009 :

Posted: Tue Oct 06, 2015 9:27 am
by admin
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.