• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Ambiguous Reference to method

 
Chacko Kallarackan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a Class as follows

class pTest{
public void add(int i,long j, long k){
System.out.println("Inside int long long");
System.out.println("Result is :"+(i+j+k));
}
public void add(long i,int j,int k){
System.out.println("Inside long,int,int");
System.out.println("Result is :"+(i+j+k));
}

public static void main(String args[]){
pTest p = new pTest();
p.add(1,4390002,438000);
}
}

But it fails to compile saying that pTest.java:13: reference to add is ambiguous, both method add(int,long,long) in pTest and method add(long,int,int) in pTest match
p.add(1,4390002,438000);

Why it is so ??


And one more. When I changed the class to

class pTest{
public void add(int i,int j, long k){
System.out.println("Inside int long long");
System.out.println("Result is :"+(i+j+k));
}
public void add(int i,long j,long k){
System.out.println("Inside long,int,int");
System.out.println("Result is :"+(i+j+k));
}

public static void main(String args[]){
pTest p = new pTest();
p.add(1,2,3);
}
}

it compiles and runs. Result is

Inside int long long
Result is :6
I'm Confused....Plz Do help..
 
Stefan Wagner
Ranch Hand
Posts: 1923
Linux Postgres Database Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What did you expect, and why?

Note that in the second example, your output is misguiding:


and please use code tags.
 
Chacko Kallarackan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the first one I'm calling the first method with the parameters int,long,long. So I expect it should call the first method. I mean add(int,long,long).


Sorry for the second part. I just changed the method signature. Forgot to change the message.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem here is that, when a value is passed to a mathod, it may be automatically converted to a wider data type. For example, this is perfectly legal:



This is valid because a byte can be safely converted to an int. Therefore, an implicit cast takes place prior to invocation of the doIt method. You don't actually send a byte to doIt, you send an int to doIt. That int was created by implicitly widening the original byte value.

In your case, you have three integer literals. In Java, a numeric literal is considered an int. Therefore, you're trying to pass 3 ints to a method. The compiler then looks for any methods by that name that can take 3 ints. There is no such method, but there are these other two that can take combinations of ints and longs. Well, an int can be converted to a long, so these methods are applicable.

The problem is, which method would you choose? The compiler has no way of knowing which one is the one you want to invoke so it issues an error message.

If you change your code slightly to look like this:



or this:



you'll find that your program compiles without error. Why?

Well, a long is wider than an int so it can not be implicitly cast as one. Therefore, the first invocation must call add(int, long, long) while the second one must call add(long, int, int). There is no more ambiguity so the compilation succeeds.
 
Chacko Kallarackan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for ur reply. I'm clear about that part. But I still have a confusion about the following.

------------------------------------------------------
class pTest{
public void add(int i,int j, long k){
System.out.println("Inside int int long");
System.out.println("Result is :"+(i+j+k));
}
public void add(int i,long j,long k){
System.out.println("Inside int,long,long");
System.out.println("Result is :"+(i+j+k));
}

public static void main(String args[]){
pTest p = new pTest();
p.add(1,2,3);
}


------------------------------------------------------

When I compile and execute this code the result is as follows.

--------------------------------------------------------------
Inside int int long
Result is :6
--------------------------------------------------------------

On what basis can we predict that this particular method will be called ?? Is there any order of pushing these arguments?? I know in C the arguments are pushed in to the stack from right to left?? Is it same in JAVA also??

Thanks In advance
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Chacko Kallarackan:
On what basis can we predict that this particular method will be called ?? Is there any order of pushing these arguments?? I know in C the arguments are pushed in to the stack from right to left?? Is it same in JAVA also??


No, Java uses a "the most specific method".

Method a is more specific than method b if all possible parameters for a would also be valid for b, but not the other way around.

That is

add(int, int, long)

is more specific than

add(int, long, long)

because every call to the former would also be a valid call to the latter, but there are valid parameters for the latter you can't use to call the former.

On the other hand, there is no such relationship between add(int, long, long) and add(long, int, int) - you can both find a parameter list that is valid for the first but not the second, *and* the other way round. Therefore your call with three int parameters was ambigous.

Does that help?
 
Chacko Kallarackan
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That Clears all my doubts. Thanks a lot.
 
Pablo Marmol
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!

I don't understand this. I wrote the code and java.exe throws a compiler error saying that the method call is ambiguous... Why?


On the other hand, there is no such relationship between add(int, long, long) and add(long, int, int) - you can both find a parameter list that is valid for the first but not the second, *and* the other way round. Therefore your call with three int parameters was ambigous.


The call doIt(1,2,3) is (in my opinion) valid for add(int, long, long) and for add(long, int, int), but the second "add" is more specific than first, because the first "add" needs two int to long conversions, and the second "add" only needs one int to long conversion... i think... or not?

I am and and

Thank you very much in advance!
 
Campbell Ritchie
Sheriff
Pie
Posts: 49844
70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
kaku kohli,
Your post was moved to a new topic.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic