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

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

ETS User

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

Post by ETS User »

ID is a static instance variable from Super. Should it be inherited?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

Deepa

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

Post 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.

icepeanuts
Posts: 53
Joined: Thu Nov 22, 2012 12:01 am
Contact:

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

Post 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?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

icepeanuts
Posts: 53
Joined: Thu Nov 22, 2012 12:01 am
Contact:

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

Post by icepeanuts »

much better explanation. Thank you, Paul.

Sweetpin2
Posts: 27
Joined: Thu Feb 07, 2013 9:46 pm
Contact:

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

Post 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?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
Last edited by admin on Thu Oct 22, 2015 8:54 pm, edited 1 time in total.
Reason: Corrected explanation later.
If you like our products and services, please help us by posting your review here.

Crashtest
Posts: 18
Joined: Fri May 31, 2013 1:18 pm
Contact:

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

Post 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

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin »

If you like our products and services, please help us by posting your review here.

Crashtest
Posts: 18
Joined: Fri May 31, 2013 1:18 pm
Contact:

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

Post by Crashtest »

Thank you. This is a real brainer to me.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

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

Post 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?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

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

Post 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

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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?
If you like our products and services, please help us by posting your review here.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

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

Post 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?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

javaman
Posts: 33
Joined: Wed Nov 13, 2013 4:11 pm
Contact:

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

Post by javaman »

Ah... thanks for putting that straight.

vchhang
Posts: 36
Joined: Tue May 06, 2014 8:30 am
Contact:

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

Post 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?

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

lorraine
Posts: 3
Joined: Tue Nov 26, 2013 11:03 am
Contact:

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

Post 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

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

ElizabethCM
Posts: 29
Joined: Sun Apr 05, 2015 11:26 am
Contact:

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

Post 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

heleneshaikh
Posts: 24
Joined: Wed Sep 02, 2015 3:43 am
Contact:

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

Post 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!
}

admin
Site Admin
Posts: 10045
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post 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.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: No registered users and 49 guests