Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #39615 > unrolled thread

Java Overloading rules confusion

Started byWayne <wayne@nospam.invalid>
First post2020-10-08 22:47 -0400
Last post2020-10-09 22:51 -0400
Articles 6 — 4 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Java Overloading rules confusion Wayne <wayne@nospam.invalid> - 2020-10-08 22:47 -0400
    Re: Java Overloading rules confusion Marcel Mueller <news.5.maazl@spamgourmet.org> - 2020-10-09 09:01 +0200
    Re: Java Overloading rules confusion Eric Sosman <esosman@comcast-dot-net.invalid> - 2020-10-09 09:21 -0400
      Re: Java Overloading rules confusion Wayne <wayne@nospam.invalid> - 2020-10-09 22:51 -0400
    Re: Java Overloading rules confusion Arne Vajhøj <arne@vajhoej.dk> - 2020-10-09 09:59 -0400
      Re: Java Overloading rules confusion Wayne <wayne@nospam.invalid> - 2020-10-09 22:51 -0400

#39615 — Java Overloading rules confusion

FromWayne <wayne@nospam.invalid>
Date2020-10-08 22:47 -0400
SubjectJava Overloading rules confusion
Message-ID<rloivp$k46$1@dont-email.me>
I have a question on overloading in Java.  I find the language
specifications confusing on this issue.

Why will this:

class Foo {
     public static void main ( String[] args ) {
         m(3, 4);
     }
     static void m (double d1, int i2) {
         System.out.println( "m(d,i)" );
     }
     static void m (float f1, int i2) {
         System.out.println( "m(f,i)" );
     }
}

Compile and run, producing "m(f,i)", but this:
class Foo {
     public static void main ( String[] args ) {
         m(3, 4);
     }
     static void m (double d1, int i2) {
         System.out.println( "m(d,i)" );
     }
     static void m (int i1, float f2) {
         System.out.println( "m(i,f)" );
     }
}

does not compile and gives this error:
Foo.java:3: error: reference to m is ambiguous
         m(3, 4);
         ^
   both method m(double,int) in Foo and method m(int,float) in Foo match

Shouldn't "m(int,float)" be more specific than "m(double,int)"?

(This works IF you change the first m(double,int) to m(int,double).)

-- 
Wayne

[toc] | [next] | [standalone]


#39616

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2020-10-09 09:01 +0200
Message-ID<rlp1sc$61a$1@gwaiyur.mb-net.net>
In reply to#39615
Am 09.10.20 um 04:47 schrieb Wayne:
> Why will this:
> 
> class Foo {
>      public static void main ( String[] args ) {
>          m(3, 4);
>      }
>      static void m (double d1, int i2) {
>          System.out.println( "m(d,i)" );
>      }
>      static void m (float f1, int i2) {
>          System.out.println( "m(f,i)" );
>      }
> }
> 
> Compile and run, producing "m(f,i)", but this:
> class Foo {
>      public static void main ( String[] args ) {
>          m(3, 4);
>      }
>      static void m (double d1, int i2) {
>          System.out.println( "m(d,i)" );
>      }
>      static void m (int i1, float f2) {
>          System.out.println( "m(i,f)" );
>      }
> }
> 
> does not compile and gives this error:
> Foo.java:3: error: reference to m is ambiguous

Very interesting!

 From my point of view this is a bug. But probably it is conformant to 
the rules.

Different widening conversions (float vs. double) do not have different 
priorities when searching for the most specific method during overload 
resolution. So both methods in example 2 have one parameter that 
requires a widening conversion.

But on the other side, widening conversions follow the sequence byte, 
short, int, long, float, double. So int -> float is preferred over int 
-> double. (This is curious anyways because the first can cause loss of 
precision while the latter does not.)
So the call is /not/ ambiguous when the different widening conversions 
apply to the /same/ parameter. Then the priority applies.

Not intuitive, not very helpful, but this seems to be the rules.


Marcel

[toc] | [prev] | [next] | [standalone]


#39617

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2020-10-09 09:21 -0400
Message-ID<rlpo5m$91o$1@dont-email.me>
In reply to#39615
On 10/8/2020 10:47 PM, Wayne wrote:
> I have a question on overloading in Java.  [...]
> 
> Shouldn't "m(int,float)" be more specific than "m(double,int)"?

     Had to spend some time studying JLS 15.12.2.5 to find that the
answer is "No."  There's a lot if niggly detail in the JLS, but for
me the easiest explanation comes in the introductory section:

	"The informal intuition is that one method is more specific
	than another if any invocation handled by the first method
	could be passed on to the other one without a compile-time
	error."

Let's try this out with your two versions of m().  Clearly, both
versions could (in isolation) handle m(3,4) or m('3',4) and many
other invocations.  However, m(3,4.0f) would work only with the
(int,float) version, but only (double,int) could handle m(3.0,4).
That is, for each version there is an invocation that it could
accept but would not work with the other.  So (says "informal
intuition") neither is "more specific" than the other, because
each has valid invocations the other could not accept.

     Interesting query.  Thanks!

-- 
esosman@comcast-dot-net.invalid
If he's so rich, why ain't he smart?
One hundred three days to go.

[toc] | [prev] | [next] | [standalone]


#39622

FromWayne <wayne@nospam.invalid>
Date2020-10-09 22:51 -0400
Message-ID<rlr7jo$qcg$2@dont-email.me>
In reply to#39617
On 10/9/2020 9:21 AM, Eric Sosman wrote:
> On 10/8/2020 10:47 PM, Wayne wrote:
>> I have a question on overloading in Java.  [...]
>>
>> Shouldn't "m(int,float)" be more specific than "m(double,int)"?
> 
>      Had to spend some time studying JLS 15.12.2.5 to find that the
> answer is "No."  There's a lot if niggly detail in the JLS, but for
> me the easiest explanation comes in the introductory section:
> 
>      "The informal intuition is that one method is more specific
>      than another if any invocation handled by the first method
>      could be passed on to the other one without a compile-time
>      error."
> 
> Let's try this out with your two versions of m().  Clearly, both
> versions could (in isolation) handle m(3,4) or m('3',4) and many
> other invocations.  However, m(3,4.0f) would work only with the
> (int,float) version, but only (double,int) could handle m(3.0,4).
> That is, for each version there is an invocation that it could
> accept but would not work with the other.  So (says "informal
> intuition") neither is "more specific" than the other, because
> each has valid invocations the other could not accept.
> 
>      Interesting query.  Thanks!
> 

I appreciate your reply, it does help.  Thanks!

[toc] | [prev] | [next] | [standalone]


#39618

FromArne Vajhøj <arne@vajhoej.dk>
Date2020-10-09 09:59 -0400
Message-ID<rlpqcl$gk8$1@gioia.aioe.org>
In reply to#39615
On 10/8/2020 10:47 PM, Wayne wrote:
> I have a question on overloading in Java.  I find the language
> specifications confusing on this issue.
> 
> Why will this:
> 
> class Foo {
>      public static void main ( String[] args ) {
>          m(3, 4);
>      }
>      static void m (double d1, int i2) {
>          System.out.println( "m(d,i)" );
>      }
>      static void m (float f1, int i2) {
>          System.out.println( "m(f,i)" );
>      }
> }
> 
> Compile and run, producing "m(f,i)", but this:
> class Foo {
>      public static void main ( String[] args ) {
>          m(3, 4);
>      }
>      static void m (double d1, int i2) {
>          System.out.println( "m(d,i)" );
>      }
>      static void m (int i1, float f2) {
>          System.out.println( "m(i,f)" );
>      }
> }
> 
> does not compile and gives this error:
> Foo.java:3: error: reference to m is ambiguous
>          m(3, 4);
>          ^
>    both method m(double,int) in Foo and method m(int,float) in Foo match
> 
> Shouldn't "m(int,float)" be more specific than "m(double,int)"?
> 
> (This works IF you change the first m(double,int) to m(int,double).)

There are some explanation in JLS (other have already elaborated
on that).

But I would like to point out the obvious: the first code
may compile, but it is still bad code.

Code where the reader needs to remember some subtle
language rules to understand why the code does what
it does is bad code.

Arne



[toc] | [prev] | [next] | [standalone]


#39623

FromWayne <wayne@nospam.invalid>
Date2020-10-09 22:51 -0400
Message-ID<rlr7ju$qcg$3@dont-email.me>
In reply to#39618
On 10/9/2020 9:59 AM, Arne Vajhøj wrote:
 > ...
> But I would like to point out the obvious: the first code
> may compile, but it is still bad code.
> 
> Code where the reader needs to remember some subtle
> language rules to understand why the code does what
> it does is bad code.
> 
> Arne

I agree.  I was trying to post a minimal example that shows
the issue.  It is indeed poor code for any real project.

-- 
Wayne

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web