File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Covariant Return Types 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 "Covariant Return Types" Watch "Covariant Return Types" New topic
Author

Covariant Return Types

Deepthi Kanakam Rajan
Greenhorn

Joined: May 15, 2006
Posts: 13
The following code:

class A
{
int x=5;
}

class B extends A
{
int x=6;
}

public class CovariantTest
{
public A getObject()
{
return new A();
}

public static void main(String args[])
{
CovariantTest c1 = new SubCovariantTest();

System.out.println(c1.getObject().x);
}
}

class SubCovariantTest extends CovariantTest
{
public B getObject()
{
return new B();
}
}


The answer given is 5 though i feel is should have been 6.

Can someone please clarify this.

Thanks in advance.
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
The "int x" declaration in class B "shadows" the one in class A, and thus does NOT participate in the inheritance.

If class B simply inherited "x" instead of declaring its own version, the result would be what you had expected.


-Ade<br /><a href="http://www.barkah.org" target="_blank" rel="nofollow">www.barkah.org</a>
wise owen
Ranch Hand

Joined: Feb 02, 2006
Posts: 2023
How do covariant overriding methods work?
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
Sorry, but the explanation provided in that link is wrong. This issue has nothing to do with covariant returns really.

For example, if we modify SubCovariantObj.getObject() to return A instead of B (so there is no covariant return at all), the answer would still be the same.
wise owen
Ranch Hand

Joined: Feb 02, 2006
Posts: 2023
Check this thread.
Sai Surya
Ranch Hand

Joined: Feb 08, 2006
Posts: 460

The correct answer I believe is OVERRIDING will NOT be applied to variables. What variable to access in the above case is decided based on Reference type and NOT on actual type.

Try adding code to return x, like int getX() { return x; } in each class A and B, and call that getX() instead of directly showing x, it will print 6.

Hope this clears your doubt.

- Surya.


Sai Surya, SCJP 5.0, SCWCD 5.0, IBM 833 834
http://sai-surya-talk.blogspot.com, I believe in Murphy's law.
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
Right!

wise owen: Try it yourself. Modify SubCovariantObj.getObject() to return A instead of B, i.e., "public A getObject()", so there is no covariant return, and therefore no "synthetic bridge".

How come the result is still the same? Because covariant returns has nothing to do it this issue!

Maybe we should review this link instead.
wise owen
Ranch Hand

Joined: Feb 02, 2006
Posts: 2023
Instance variables, static variables, static overridden methods (it looks like it's an override, but actually hidden), and overloaded methods are all bound at compile time.

Compiler need to know what "c1.getObject()" is for "x". Calling getX() is Run time binding and this kind of binding depends on the instance object type.
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Objection, your honor!


Ade Barkah wrote:
Sorry, but the explanation provided in that link is wrong. This issue has nothing to do with covariant returns really.



Well it has. And it has nothing to do with shadowing.
If you have
CovariantTest c1 = new SubCovariantTest();
in the main method, and you call
getObject()
on c1, then the synthetic bridge (see link of wise) will come into play.

The object returned by getObject will be an A, not a B.
The code will not compile if you add
B test = c1.getObject();
into your main method

A test = c1.getObject();
would be fine.




Yours,
Bu.


all events occur in real time
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
Then please explain why the code below, which has NO covariant return, and therefore no bridging method whatsoever, still return the SAME result.

You can't have it both ways.

Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
Originally posted by Ade Barkah:
Then please explain why the code below, which has NO covariant return, and therefore no bridging method whatsoever, still return the SAME result.

You can't have it both ways.



Because the method you provided has the same return type as the bridge method.

This is the result of javap on the original SubCovariantTest.

Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
Nah, the modified example I provided above would return the same result even under JDK 1.4. :roll:

The behavior hasn't much to do with covariant returns, then, obviously if the same exact result can be obtained: a) when covariant return is used; b) when covariant returned is not used; and c) under a JDK when covariant returns didn't even existed.
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
But the SubCovariantTest program wouldn't compile under 1.4.
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi ranchers,


Ade Barkah wrote:
Nah, the modified example I provided above would return the same result even under JDK 1.4.

Your example is irrelevant as there are only A reference types returned.
The real question is, what the lines



do.

The real question is: What will c1.getObject() return, an A or a B?
I'm speaking about reference type (or compile type), not about the type of the object. And reference type surely is a matter of covariance.

The key is, that c1.getObject() returns an A-type and not a B-type as you would expect in the first place.
I said it again, try

after the above lines.
It will not compile, as the super class A will be returned.

The fact that

will produce two fives has never been debated.



Yours,
Bu.
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
I guess we can agree to disagree. My last reply to this topic.

I leave you with a piece of code below... which is ALL that is actually happening. The rest of the fluff (covariant, bridging, etc.) are simply red-herrings. Feel free to use any JDK.



Result: 5
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
I fail to see the relevance of that code. You're simply demonstrating that instance variables are hidden, not overridden.
Ade Barkah
Ranch Hand

Joined: Mar 17, 2004
Posts: 65
Ooops, sorry Burkhard replied while I was typing.

Burkhard: you write "The key is, that c1.getObject() returns an A-type and not a B-type as you would expect in the first place."

No, in fact c1.getObject() returns a B-type, as one would normally expect. Please verify this yourself.

Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Ade Barkah wrote:
... which is ALL that is actually happening. The rest of the fluff (covariant, bridging, etc.) are simply red-herrings. Feel free to use any JDK.


Yep!




;-)

Bu.
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Ade Barkah wrote also:
No, in fact c1.getObject() returns a B-type, as one would normally expect. Please verify this yourself.





c1.getObject returns an object of type B, whose reference type is A (and not B).
This can be stored into reference type Object, sure.
And prints out B@hash something, sure.

But



Compiler says:


The second line cannot compile, because the reference type of c1.getObject() is A.
The last line compiles, cause the object returned here is of reference type A, with an object type of B. But that the object type is B was also printed out in Ade's code above already.
And never been debated, as the output of the original post (see way above) depends only on the reference type, not the object type.



Yours,
Bu.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Covariant Return Types