aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Why this output? (in Java 5.0) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Why this output? (in Java 5.0)" Watch "Why this output? (in Java 5.0)" New topic
Author

Why this output? (in Java 5.0)

Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Hi Ranchers,

I am not able to figure out why the output of following code is 5 after printing In B

The type of c.getObject() is B. Since we are hiding the int x of A. So B's x must be called.



Thanks in advance

Naseem

[ July 17, 2006: Message edited by: Naseem Khan ]

(topic edited to mention Java 5.0)
[ July 18, 2006: Message edited by: Barry Gaunt ]

Asking Smart Questions FAQ - How To Put Your Code In Code Tags
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
The type of the object returned by c.getObject() is not B, but A. Since "c" is a reference to an object of type CovariantTest, the getObject() method which is invoked in the "println" is the one in CovariantTest. That's why you get an object of type A.

If you want to get an object of type B, you should cast the "c" reference as follows:



This will give you the result you expected.


Preparing SCJP 1.5
wise owen
Ranch Hand

Joined: Feb 02, 2006
Posts: 2023
this thread
Jeronimo Sanchez
Greenhorn

Joined: Jul 17, 2006
Posts: 23
Sorry. My explanation is not coorect.
You are completely right!

The object returned by c.getObject() is of type B.

Let me think about it again ;-)
Jack Lee
Ranch Hand

Joined: Jun 06, 2006
Posts: 38
First I thought the answer is:
In B
6

But I compile and run the code, The answer is
In B
5

The overriden method getObject of B is called (Polymorphism), "In B" is printed and an object of type B is returned.

But object c is type CovariantTest. Therefore, in the place of c.getObject(), the return type is considered as type A. 6 is printed.


SCJP 5.0<br />SCWCD 1.4
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
Thanks everyone. I got this now.

Naseem
Shaan Shar
Ranch Hand

Joined: Dec 27, 2005
Posts: 1249

Originally posted by Naseem Khan:
Thanks everyone. I got this now.

Naseem



What the hell is JVM working it's totally ambigous from your statements.. Actually When I tried the code and run it.

It is giving output:

In A
5



Now I am totally confused what is the going on in JVM......



The Best way to predict your future is to create it - Every great individual common man
Shaan Shar
Ranch Hand

Joined: Dec 27, 2005
Posts: 1249

One more thing I want to tell you that...

I am using Websphere Studion Application Developer Studio as IDE for JAVA development when I copied this code...

WSAD IDE was showing some error e.g
"The return type is incompatible with CovariantTest.getObject()".

And I thought that program is throwing compile time exception..

And when I tried to run it... it runs smoothly.. and gives the out put like:::----->>>

In A
5



Now what is this please explain this one... it's really ambigous.???
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
"The return type is incompatible with CovariantTest.getObject()".


Looks like you have set up your IDE to use Java 1.4 not Java 5.0.

The program compiles and runs using plain vanilla Java 5.0 at the command line so let's forget using IDE's.


Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
ram gaurav
Ranch Hand

Joined: Mar 29, 2006
Posts: 208
Above i think that you are breaking the overriding policy straight forward.

class SubCovariantTest extends CovariantTest

in this class you override , getObject() , and you just change the return type of the methord , which is just compile time error , there is no question of executing this code.

Thanks
Regards
Gaurav
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Jack wrote:
But object c is type CovariantTest. Therefore, in the place of c.getObject(), the return type is considered as type A. 6 is printed.


Unless this is a typo, 6 is not printed - it prints 5.

The returned object from the overridden getObject() is of type B (which is also of type A) and it contains two x values. 5 in the base class A and 6 in the subclass B. Now, as you wrote, the object has to be treated as an object of type A because CovariantTest's getObject() method returns objects of type A. So on dereferencing the x of the return object we get the A.x not the B.x. So 5 is the printed output.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Originally posted by ram gaurav:
Above i think that you are breaking the overriding policy straight forward.

class SubCovariantTest extends CovariantTest

in this class you override , getObject() , and you just change the return type of the methord , which is just compile time error , there is no question of executing this code.


No. In Java 5.0 you can do this, but not in Java 1.4 or previous versions.
Shaan Shar
Ranch Hand

Joined: Dec 27, 2005
Posts: 1249

Originally posted by Barry Gaunt:


No. In Java 5.0 you can do this, but not in Java 1.4 or previous versions.


That means I was correct at my point, that this is a compile time exception But why it was running and giving me wrong output which was not desirable...


Rajah Nagur
Ranch Hand

Joined: Nov 06, 2002
Posts: 239
Barry Gaunt is right. This works only in JDK 5 (it is a new feature) and above not in previous versions. This page on Sun website gives more clarity on covariant types.

Comming to above question:
The returned object of the method call c.getObject() is of type B. This is determined at runtime. Since B is a subclass of A, the returned object is also of type A.
so c.getObject definitetly instantiates Object B (Which in turn instantiates A as it is a superclass).

But the variable that is printed c.getObject().x is determined at compile time. The return type of c.getObject is A and the x value of A is printed.

I did a javap -c on the CovariantTest.class to verify. Below is the output:



Look at the above line 15. The field A.x is bound at compile time.

So the output is 5.

(Disabled smilies)
[ July 18, 2006: Message edited by: Barry Gaunt ]

You can't wake a person who is <b><i>pretending</i></b> to be asleep.<br />Like what <b>"it"</b> does not like - <i> Gurdjieff </i>
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Originally posted by Ankur Sharma:


That means I was correct at my point, that this is a compile time exception But why it was running and giving me wrong output which was not desirable...




There is no compile time exception in Java 5.0. We are discussing Covariant return types, a new version 5.0 feature. Do not confuse the issue by bringing in Java 1.4. Of course you will get a compiler error in Java 1.4. I suggest that you check that your IDE compiler is correctly set up to use Java 5.0, and compile and run the program. If you have problems setting up your IDE then try our IDE forum.
Arun Maalik
Ranch Hand

Joined: Oct 25, 2005
Posts: 216
Sir your program written there is completly wrong. It will create a compile time error that you are not overwriding the method.

Arun
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
Originally posted by Arun Maalik:
Sir your program written there is completly wrong. It will create a compile time error that you are not overwriding the method.

Arun


Not in 1.5
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Thanks Keith.
For the benefit of those posters who do not know that we are discussing Java 5.0 in this topic, and those who have not bothered to read what was written before they posted, I have modified the topic title to explicitly mention Java 5.0.
Anthony Karta
Ranch Hand

Joined: Aug 09, 2004
Posts: 342
Could someone explain once more in deep detail?

I use "instanceof" test and it IS an object of type B is returned.

why the return type is considered as type A, and 6 is printed? :roll: sleep


SCJP 5
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809

I use "instanceof" test and it IS an object of type B is returned.


Even if you check instanceof A or instanceof Object all will give you true value.

Covariant return type is a feature of java 1.5 as Barry edited my subject line.

Naseem
Anthony Karta
Ranch Hand

Joined: Aug 09, 2004
Posts: 342
I guess we should avoid giving instance variable the same name as superclass??

or we shouldn't use covariant return at all in practice??


so c.getObject definitetly instantiates Object B (Which in turn instantiates A as it is a superclass)


does that mean all superclasses in hierarchy tree will be instantiated during runtime?
Ajit Amitav Das
Ranch Hand

Joined: Dec 14, 2005
Posts: 49
first i used this code in eclipse which is using jre1.4 , it gave me compilation error , but in jdk1.5 it complies and runs fine , method binding and data member binding are different , there is no concept of datamember overriding it is just hiding and if u have a datamember in super class and with exact name in subclass then subclass variable hide superclass datamember and u just need same name not even same type also(same name is sufficent for datamember hiding ).Imporant point to note here is "when an instance method is invoked on an object using a refernce it is the class of the current object denoted by the object not the type of reference that determines which method implementation will be executed.But incase of a field(data member) of an object is accesed using a reference, it is the type of reference not the class of the current object denoted by the reference that determines which field will actually will be accessed."


Warm Regards<br />Ajit Amitav Das<br />SCJP 1.5
saikrishna cinux
Ranch Hand

Joined: Apr 16, 2005
Posts: 689
I think now this code compiles in jdk1.4 version


but the output is same


A = HARDWORK B = LUCK/FATE If C=(A+B) then C=SUCCESSFUL IN LIFE else C=FAILURE IN LIFE
SCJP 1.4
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Why are you people bringing in Java 1.4? This topic is about a Java 5.0 feature: Covariant returns. We know it does not work in Java 1.4.

Covariant Return Types
[ July 19, 2006: Message edited by: Barry Gaunt ]
Pinkal Patel
Ranch Hand

Joined: Jun 16, 2006
Posts: 57
c.getObject().x


Here c refferance of class CovariantTest
And Assigned the Object of SubCovariantTest

Meance Signature of the Method is


Runtime Method called from class SubCovariantTest


Now Return type B is Used fetured of Covariant returntype and convert this object to A.

So O/P is In B followed with 5.

Due to Calling Method of SubCovariantTest and return object is convert to Type A.


Pinkal Patel<br />SCJP 1.5<br />Preparing for SCWCD
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
This is a very interesting question. Some information can be obtained by looking at the bytecode that is generated.

Consider this example.



After compiling and running javap on Test2, the output is



So I think a reasonable surmise is that in the subclass which overrides a method from a superclass using a refined return type, the return type is determined by the reference type of the caller. That is, if called with a superclass reference, the return type of the method will be determined by the most specific return type that the superclass reference can see.
Naseem Khan
Ranch Hand

Joined: Apr 25, 2005
Posts: 809
I just made a little twist in my code and I think from the error every thing will be clear why 5 gets printed not 6.



Befor calling x, I assigned the reference of c.getObject() in B. As c.getObject() is returning an instance of B, assignment at line 2 must be valid. But its not.

You will get compilation time error at line 2...


incompatible types
found : A
required: B
B b=c.getObject();


It means what compiler sees c.getObject() as of type A.

One more thing, c.getObject can only be assigned to A or superclass of A not B.

A.x---->>>5

Naseem
Anthony Karta
Ranch Hand

Joined: Aug 09, 2004
Posts: 342
Originally posted by Naseem Khan:


You will get compilation time error at line 2...
It means what compiler sees c.getObject() as of type A.
Naseem[/QB]


In compile time, "reference type" Always determines which methods/variables can be called, that's why compiler will sees c.getObject() as of type A.

But the issue is, during run-time, c.getObject() is object of type B.
nitin pokhriyal
Ranch Hand

Joined: May 19, 2005
Posts: 263
hi naseem,

can you clarify your answer a bit more? at runtime getObject() of subCovarient will be called. am i right? if yes then how can it return object of A?

Regards,
nitin
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Originally posted by nitin pokhriyal:
hi naseem,

can you clarify your answer a bit more? at runtime getObject() of subCovarient will be called. am i right? if yes then how can it return object of A?

Regards,
nitin


Does this say anything about class B?

Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Following on from Naseem's most recent post, here is another version of the main method based on his example:



To force 6 out of this thing you have to use a cast:


[ July 20, 2006: Message edited by: Barry Gaunt ]
nitin pokhriyal
Ranch Hand

Joined: May 19, 2005
Posts: 263
Barry, i got your point, thanks. Sorry for earlier post but there was a difference what i wanted to ask and what i wrote.. it was totally due to that? sorry once again and thanks for your reply.

Regards,
nitin
Akhil Sharma
Greenhorn

Joined: Jul 20, 2006
Posts: 1
Just try this simple code:

import static java.lang.System.out;

class A {
int x=5;
public getInt(){
return x;
}
}
class B {
int x=6;
public getInt(){
return x;
}
}
public class Test{
public static void main(String... args){

A a = new A();
B b = new B();
A ab = new B();

out.println(a.x);
out.println(b.x);
out.println(ab.x);
out.println(a.getInt());
out.println(b.getInt());
out.println(ab.getInt());
}

You can easily see that when we print a.x, b.x and ab.x we get the integer values of the instances variables of classes with whose reference is used with the . operator. But when we start using the overridden method the polymorphism comes into picture and the run time class of the ab variable is determined and corresponding getInt() from extended class B is called even though the reference variable used to call the method is of type A. I hope you guys will easily understand this.
Enjoy the code...


}
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
Going back to the original code, this is the output of javap on SubCovariantTest.



The JLS talks about this kind of method in relation to generic methods. The method public A getObject() that is included as part of the bytecode of SubCovariantTest is called a bridge method.

Apparently what's happening is that when the runtime type of the object is SubCovariantTest, a call to getObject() still invokes the overridden method by polymorphism, but if the reference type is CovariantTest, then the call is made through the bridge method, and so the return type in that case is A.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why this output? (in Java 5.0)