File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

reference to method1 is ambiguous ..... java can't decide whic one to call.

 
sean cee
Ranch Hand
Posts: 115
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,
I have the following problem.
----------------------------------------
class Base {
method1(int, int) {...}
method1(double, double) {...}
}
public class Sub extends Base{
method1(double,double) {...}
main{
method1(1,1); //* Compile Error!
}
}
when compiled I get :
reference to method1 is ambiguous, both method method1(int,int) in Base and method method1(double,double) in Sub match.
When I had Base class only, from main statements like method1(1,1) and method1(1.0,1.0) had no trouble finding corresponding (overloaded)methods
but when I subclassed Base and override double version it complains as above..
I thought java looks for the most specific one (in this case since method1(1,1)'s 1 is int, and there was no implementation for method1(int,int) in Sub it will end up calling Base's method1(int,int) but it is saying it is ambiguous...
Can anyone shed light on this?
just for a comparison the following is ok though:
-------------------------------------------------
class Base {
method1(int, int){..}
method1(double, double){..}
}
public class Sub {
method1(int,int){..}
main{
method1(1,1); //** OK!!
}
}
thanks in advance
 
Valentin Crettaz
Gold Digger
Sheriff
Posts: 7610
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should have a quick look at JLS 15.12.2.1 Find Methods that are Applicable and Accessible (and following paragraphs) first, and then, if you still wonder why this is happening, come back and we will shed some light on the problem
 
yogesh sood
Ranch Hand
Posts: 108
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Im
ok most specific method will be called
so Class Sub having two methods
1. method1(int,int) /*inherited from Base class*/
2. method1(double,double) /* Overide*/
so when i say
method1(1,1);
more specific is method no. 1 inherited from Base class.

Now Where the Problem Lies....

 
sean cee
Ranch Hand
Posts: 115
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Yogesh
I had the same answer as you do.. but if you
actually compile the code you will get the following compile time error:
reference to method1 is ambiguous, both method method1(int,int) in Base and method method1(double,double) in Sub match.
Strange huh?
Anyone got any idea?
 
Val Lee
Ranch Hand
Posts: 41
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Look my code!No compile error!
correct me if I wrong!
 
sean cee
Ranch Hand
Posts: 115
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Thanks for your reply however your example is different from mine in that you have i for int and d for double.
but mine has same method name for all.
So your code will compile.
 
Val Lee
Ranch Hand
Posts: 41
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
oh!I wrong!
 
sean cee
Ranch Hand
Posts: 115
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey,
For those of you who wants to help me out,
here is the "ready-to-compile" version of the code
that is giving me a hard time.
class Base {
void method1(int a, int b) {}
void method1(double a, double b) {}
}
public class Sub extends Base{
void method1(double a,double b) {}
public static void main(String Args[]){
new Sub().method1(1,1); //Compile Error!
}
}
Thanks
 
Valentin Crettaz
Gold Digger
Sheriff
Posts: 7610
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First off, do you admit that
void method1(double a, double b)
in class Sub overrides
void method1(double a, double b)
in class Base? I guess you do. So the code can be changed to the following without impacting anything, just removing some clutter:
Note: we can do so since no reference of type Base is used within the program. We can assume that from the compiler's perspective the code looks as presented below.

Now the problem boils down to method1 being overloaded.
Both methods are applicable since the arguments (1,1) suit both method signatures (as defined in JLS 15.12.2.1 Find Methods that are Applicable and Accessible). Both methods are also accessible (see access modifiers).
We now have two applicable and accessible methods named method1, one taking two int primitives and the second taking to double primitives as arguments. Which one to choose? Java chooses the "most specific one".
The JLS (15.12.2.2 Choose the Most Specific Method) gives two definitions of what "most specific method" means, one informal and one formal.
The informal says that:

one method declaration 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 type error.

This means that the most specific method here is method1 taking two int primitives as arguments simply because int primitives can be converted to double primitives by assignment conversion, but not the opposite (conversion from double to int is not allowed).
On the other hand, the formal definition gives the final clue as to why there is no most specific method.

Let m be a name and suppose that there are two declarations of methods named m, each having n parameters. Suppose that one declaration appears within a class or interface T and that the types of the parameters are T1, . . . , Tn; suppose moreover that the other declaration appears within a class or interface U and that the types of the parameters are U1, . . . , Un. Then the method m declared in T is more specific than the method m declared in U if and only if both of the following are true:
1. T can be converted to U by method invocation conversion.
2. Tj can be converted to Uj by method invocation conversion, for all j from 1 to n.

Let's apply this definition to our case:
m is method1
n is 2
T is Sub
U is Base
T1 is double, T2 is double
U1 is int, U2 is int
Now, Sub (T) can be converted to Base (U) by method invocation conversion (which are identity conversions and widening conversions), that is, an object of type Sub can be referenced by a reference variable of type Base. So the first point is correct, BUT, the second is not.
double (T1) cannot be converted to int (U1) by method invocation conversion.
The first point being ok but the second not makes that there is no most-specific method, and thus, the method invocation is ambiguous...
 
sean cee
Ranch Hand
Posts: 115
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Valentin,
Thanks alot for your precise explanation.
That cleared the mud
Sean
 
yogesh sood
Ranch Hand
Posts: 108
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So near Yet So Far......
No-matter how hard u try u always learn new concept here..
whenever i think i know everything bout SCJP curriculm it happens
like this question
thanx val

There is always next time
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic