aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Covariant doubt Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Covariant doubt" Watch "Covariant doubt" New topic
Author

Covariant doubt

raja kanak
Ranch Hand

Joined: Oct 18, 2006
Posts: 135

The above code gives output "Derived" when we typecast to String at //1
If (String) removed at //1, it shows error.

method1() is overridden in class Second. When invoking method1() using First reference o, the JVM will call Second version of method1() since o refer to Second object.

If Second version of method1() returns String "Derived", they typecasting is needed at //1 ???

I don't where I missed the logic?

Thanks for any help


live
Srinivasan thoyyeti
Ranch Hand

Joined: Feb 15, 2007
Posts: 557
Hi Raja,

Compiler is not as dynamic as you.

Given:
First o = new Second();
String s = (String)o.method1();

here you are invoking method1() on reference of First i.e., o. Then compiler thinks AS o.method1 returns Object, you have to type cast it before assigning to any other class.


Thanks & Regards, T.Srinivasan
SCWCD 1.4(89%), SCJP 5.0(75%)
raja kanak
Ranch Hand

Joined: Oct 18, 2006
Posts: 135
So the term covariant return is used in Runtime environment. Am i right?
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
If you look at the bytecode, it can give you a better idea of what's happening. Consider this example.



Now look at the methods in the bytecode created from Fourth.java.



The methods listed other than the one with return type D have been added to the class definition. This is a form of bridge method that may be used in generics.

Depending on the reference type, the appropriate bridge method is invoked.

This means that if a reference of type A refers to an object of type D, and invokes the method method1(), then the first method invoked will be the one with return type A. Then the overridden method in D will be called. But it will be called from the bridge method. However, the type of object returned by the method will be A.

You can see this by what is printed out in the second set of print statements.

You know that if you access a static member of a class using an instance of the class, then the class type will be substituted by the compiler in the method call.

So first.method1().x will refer to the static variable x in the class definition which is the type of first.method1().

So 1 is printed.



If you look at the full bytecode for Fourth, you can see what's happening.


[ March 02, 2007: Message edited by: Keith Lynn ]
raja kanak
Ranch Hand

Joined: Oct 18, 2006
Posts: 135
Wonderful explanation Keith.

The methods listed other than the one with return type D have been added to the class definition. This is a form of bridge method that may be used in generics.

Depending on the reference type, the appropriate bridge method is invoked.

This means that if a reference of type A refers to an object of type D, and invokes the method method1(), then the first method invoked will be the one with return type A. Then the overridden method in D will be called. But it will be called from the bridge method. However, the type of object returned by the method will be A.

I don't know anything about bride method. Can you please explain or give me any link to learn?

You can see this by what is printed out in the second set of print statements.

I can't follow the second set of print statement
I guess the answer hidden behind bridge method!!


You know that if you access a static member of a class using an instance of the class, then the class type will be substituted by the compiler in the method call.

So first.method1().x will refer to the static variable x in the class definition which is the type of first.method1().

So 1 is printed.

This point is clear.
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
There's not much discussion about it in the Java Language Specification, but here is one paragraph where they talk about bridge methods.

This is from the Java Language Specification 15.12.4.

As an example of such a situation, consider the declarations:
class C<T> { abstract T id(T x); }
class D extends C<String> { String id(String x) { return x; } }
Now, given an invocation
C c = new D();
c.id(new Object()); // fails with a ClassCastException
The erasure of the actual method being invoked, D.id(), differs in its signature from
that of the compile-time method declaration, C.id(). The former takes an argument of
type String while the latter takes an argument of type Object. The invocation fails with a
ClassCastException before the body of the method is executed.
Such situations can only arise if the program gives rise to an unchecked warning
(�5.1.9).
Implementations can enforce these semantics by creating bridge methods. In the
above example, the following bridge method would be created in class D:
Object id(Object x) { return id((String) x); }
This is the method that would actually be invoked by the Java virtual machine in
response to the call c.id(new Object()) shown above, and it will execute the cast and
fail, as required
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
The reference variable o is of type First. First has only a method1() that returns an Object. You cannot assign the returned Object to a String without a cast. It's as simple as that. I think that also is the meaning of what Srinivasan was trying to convey.


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

Joined: Oct 18, 2006
Posts: 135
Thanks for all your efforts friends.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Covariant doubt