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

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?

Online
admin
Site Admin
Posts: 10055
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

Online
admin
Site Admin
Posts: 10055
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?

Online
admin
Site Admin
Posts: 10055
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?

Online
admin
Site Admin
Posts: 10055
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

Online
admin
Site Admin
Posts: 10055
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!
}

Online
admin
Site Admin
Posts: 10055
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.

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

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

Post by heleneshaikh »

Thank you very much Paul.

andrix
Posts: 2
Joined: Wed Oct 14, 2015 7:36 pm
Contact:

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

Post by andrix »

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:
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?
And admin response was:
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.
Well... I must say.. this answer may not be quite true.

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
admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

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

Post by admin »

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

Sergio
Posts: 7
Joined: Wed Mar 23, 2016 1:39 am
Contact:

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

Post by Sergio »

Please check this: https://ideone.com/xE636D
I see ONLY
QBANK

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

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

Post by admin »

That is indeed the correct option mentioned in the question as well.
Paul.
If you like our products and services, please help us by posting your review here.

Sergio
Posts: 7
Joined: Wed Mar 23, 2016 1:39 am
Contact:

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

Post by Sergio »

no the software mention QBANK as wrong answer

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

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

Post by admin »

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.
2.1009.png
2.1009.png (27.64 KiB) Viewed 12635 times
If you like our products and services, please help us by posting your review here.

PeterD
Posts: 4
Joined: Thu Jan 26, 2017 8:45 am
Contact:

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

Post by PeterD »

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

shambhavi
Posts: 25
Joined: Fri Aug 04, 2017 12:21 am
Contact:

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

Post by shambhavi »

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 ? :roll:

I mean here, in this case, this initialization will not even be considered ! :o

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

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

Post by admin »

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.

Post Reply

Who is online

Users browsing this forum: admin and 42 guests