Re: Two methods, same signature, different return types

Martin Grigorov <[email protected]> Mon, 18 Aug 2008 00:17:31 +0300
Newsgroups gmane.comp.windows.devel.java.advanced
Organization Home
Message-ID <1219007851.7351.25.camel@martin>
Hi,

I'm not an expert in Java internals but recently I've read this article:
http://today.java.net/pub/a/today/2008/07/31/return-type-based-method-overloading.html

There the author says that if there are two methods with the same name
and parameters in the methods table in the class file the JVM will
always call the first one:
"...the Java compiler would look up the table and encode a call to the
first method having the required name and parameters..."

Looking at the output from javap I think it could be the same.

But let's hear some opinion from an expert in this stuff.

martin-g


On Sun, 2008-08-17 at 22:42 +0200, Attila Szegedi wrote:
> Hi folks,
>
> I'm mildly puzzled by something I came across today. I have a class,
> generated by plain javac (1.5.0_13, on Mac OS X) that has two methods
> that only differ in their return type. Witness:
>
> public interface BeanTestInterface<T>
> {
>      T getSomething();
> }
>
> public class BeanTest implements BeanTestInterface<Integer>
> {
>      public Integer getSomething()
>      {
>          return 42;
>      }
> }
>
> Compiling and disassembling BeanTest.class using javap shows:
>
> $ javap BeanTest
> Compiled from "BeanTest.java"
> public class BeanTest extends java.lang.Object implements
> BeanTestInterface{
>      public BeanTest();
>      public java.lang.Integer getSomething();
>      public java.lang.Object getSomething();
> }
>
> The Object returning is of course synthetic, its code is simply
> delegating to the integer version:
>
> public java.lang.Object getSomething();
>    Code:
>     0:  aload_0
>     1:  invokevirtual   #3; //Method getSomething:()Ljava/lang/Integer;
>     4:  areturn
>
> I know why the method is emitted -- if some external code invokes
> getSomething() through a reference of type BeanTestInterface<T>, i.e.
> with
>
> class BeanTestInvoker<T>
> {
>      BeanTestInterface<T> bti;
>
>     ... bti.getSomething() ...
> }
>
> javac can only compile a call the Object returning version. That's
> okay. Actually, just now I can't find this part (emitting of the
> synthetic method) anywhere in the JLS -- someone care to point out to
> me where is it?
>
> What I have trouble understanding is how does it *not* screw up the
> overloaded method resolution algorithm specified in JLS 15.2.2 -- with
> expression "new BeanTest().getSomething()" I see nothing that would
> prevent both methods to be selected as applicable, then both would
> wind up being maximally specific as per 15.12.2.5 ("more specific"
> doesn't take return type in the consideration), and the compiler would
> then have to claim ambiguity as far as I can see. Obviously (and
> fortunately) it doesn't -- it invokes the Integer returning version.
> But I'd really appreciate if someone would point it out to me what
> rule within JLS 15.2.2 allows it to avoid ambiguity in this case.
>
> Thanks,
>    Attila.
>
> --
> home: http://www.szegedi.org
> weblog: http://constc.blogspot.com
>
> ===================================
> This list is hosted by DevelopMentor  http://www.develop.com
>
> View archives and manage your subscription(s) at http://discuss.develop.com
>

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com