问题
I am working on Java Se 7 OCA and could not figure out why below code does not compile. aMethod call in main method gives compile error stating ambiguous method. Precedence rules between widening and boxing seems to clash in this overloading method sample.
public class Overloading {
public static void main(String[] args) {
Byte i = 5;
byte k = 5;
aMethod(i, k);
}
static void aMethod(byte i, Byte k) {
System.out.println("Inside 1");
}
static void aMethod(byte i, int k) {
System.out.println("Inside 2");
}
static void aMethod(Byte i, Byte k) {
System.out.println("Inside 3 ");
}
}
The error is "The method aMethod(byte, Byte) is ambiguous for the type Overloading". when I comment out first method, it gives same error for second method.
My thinking is: First method needs unboxing and boxing Second method needs unboxing and widening Third method needs only boxing. So it must be third method, since it needs the least conversion and all of them have boxing conversion.
回答1:
The problem is with all these methods:
static void aMethod(byte i, Byte k) {
System.out.println("Inside 1");
}
static void aMethod(byte i, int k) {
System.out.println("Inside 2");
}
static void aMethod(Byte i, Byte k) {
System.out.println("Inside 3 ");
}
Java doesn't know, which one it should invoke in line:
aMethod(i, k);
Your params i
and k
could be converted by various ways, according to JLS specifications:
i
could be unboxed
to byte
(5.1.8) or leaved as Byte
(5.1.1) -> 2 variants
k
could be boxed
into Byte
(5.1.7) or widened to int
type (5.1.2) -> 2 variants.
回答2:
this class you have two equal method
static void aMethod(Byte i, Byte k) {
System.out.println("Inside 3 ");
}
static void aMethod(byte i, Byte k) {
System.out.println("Inside 1");
}
Byte automatic conversion byte ,so compile error
回答3:
Actually not the definition, but the call is ambiguous. since, all the integers in java by default are, int. even if you say byte b =5, 5 would be internally converted to int for any operation. But as the reference is byte, in you case, it has option to call method 2 & 3. So compiler cant understand what to call.
so aMethod(i, (Byte)k)
should work.
回答4:
Following points should be kept in mind while method overloading in Java:
Widening of primitive types uses the immediate next wider type method argument, if exact match is not found.
Boxing and var-args are compatible with method overloading if they are used individually.
One wrapper type can't be widened to another. For example, Integer can't be widened to Long.
Widening followed by boxing does not work. For example, an int can't be passed to a Long.
Boxing followed by widening works only in one situation if boxed argument is passed to an Object type reference. An int can be passed to an Object, via Integer.
Var-args can be combined with either widening or boxing, but carefully.
In above piece of code the arguments passed to aMethod should be appropriately type-casted, because intermediate results in Java are converted in int in an int expression.
来源:https://stackoverflow.com/questions/15493313/java-method-overloading-with-boxing-widening