Java重载:数字,数字;整数,双精度
两天后我有一次java考试,我想不出这个问题的答案:Java重载:数字,数字;整数,双精度,java,overloading,Java,Overloading,两天后我有一次java考试,我想不出这个问题的答案: class ClassA { public String foo(Integer x , int y) { return "Integer, int"; } public String foo(int x, Double y) { return "int, Double"; } public String foo(Number x, Number y) { return "Number, Number"; } pub
class ClassA {
public String foo(Integer x , int y) {
return "Integer, int";
}
public String foo(int x, Double y) {
return "int, Double";
}
public String foo(Number x, Number y) {
return "Number, Number";
}
public String foo(Object x, Object y) {
return "Object, Object";
}
public static void main(String... args) {
ClassA a = new ClassA();
System.out.print(a.foo(5, 1.2f) + " ");
System.out.println(a.foo(null, null));
}
}
输出是什么
答案是:
Number, Number Number, Number
我知道java总是选择最指定的方法,这就是为什么a.foo(null,null)
将激活Number,Number
方法,而不是对象,Object
方法。
但是为什么a.foo(5,1.2f)
还可以使用Number,Number
方法,而不是int,Double
方法
但还有一件事可能会有所帮助:
如果在1.2
之后删除f
,则调用为:
a.foo(5,1.2)代码>
我得到一个编译器错误,它不能在Number,Number
和int,Double
方法之间进行选择
如果你们能给我解释一下的话,那将非常有帮助:)1.2f
不是用双精度
包装的,而是用浮点数
包装的。由于Float
不是Double
的子类(它们是Number
的不同子类),因此可以使用的最具体的方法签名是foo(Number,Number)
一旦删除f
,1.2在默认情况下将被视为double
(原语,而不是包装类),可以自动装箱到double
。但是,5也可以自动装箱为整数,从而导致歧义。这里有两个重要因素
首先,1.2f
不是一个Double
。这是一个浮动
。(int,Double)
函数根本不匹配<代码>(数字,数字)
是最合适的
第二,即使您将其更改为1.2
,它仍然不是Double
。它是一个双。也就是说,它是一个基本体,而不是一个对象。现在,Java仍然会很高兴地将一个double
传递到一个需要double
的函数中,而不会有太多抱怨,但是在这种情况下,您给了它两个有效的转换,从而混淆了它:
将5
转换为整数
并将1.2
转换为双精度
将5
保留为原语int
,但将1.2
转换为Double
没有一条规则规定哪一个更可取。Java产生一个编译器错误,即它有一个不明确的函数调用,并迫使您选择您喜欢的函数(通过手动将它们中的一个或两个包装到对象中)
另一方面,如果您有一个使用(int,double)
的方法,那么就不会有任何歧义:该方法实际上与5
和1.2
的现有类型相匹配,因此将调用它。事实上,这里的一些参数是导致混乱的包装器对象。一般答案:
public class OverloadingNumeric {
public void print(int x){
System.out.println("int");
}
public void print(long x){
System.out.println("long");
}
public void print(float x){
System.out.println("float");
}
public void print(double x){
System.out.println("double");
}
public void print(Integer x){
System.out.println("Integer");
}
public void print(Long x){
System.out.println("Long");
}
public void print(Float x){
System.out.println("Float");
}
public void print(Double x){
System.out.println("Double");
}
public void print(Number x){
System.out.println("Double");
}
public void print(Object x){
System.out.println("Object");
}
public static void main(String[] args) {
OverloadingNumeric obj = new OverloadingNumeric();
/*
* Primitives will take more precedence
* of calling instead of wrapper class arguments,
*/
obj.print(10);
obj.print(10l);
obj.print(10f);
obj.print(10d);
obj.print(10.1);
//obj.print(999999999999999); Error: this letral type int is out of range
obj.print(999999999999999l);
/*
* OUTPUT
* int
* long
* float
* double
* double
* long
*/
/*
* Assume all primitive argument methods
* are commented. then calling the same again
*/
obj.print(10);
obj.print(10l);
obj.print(10f);
obj.print(10d);
obj.print(10.1);
//obj.print((Double)10); //Cannot cast int to Double
obj.print((double)10); //Success
//obj.print((Float)10); //Cannot cast int to Float
obj.print((float)10); //Success
//obj.print(null); ERROR AMBIGUOUS
/*
* OUTPUT
* Integer
* Long
* Float
* Double
* Double
* Double
* Float
*
*/
}
}
interface SuperIfc {}
class SuperClass implements SuperIfc{}
class SubClass extends SuperClass {}
public class OverloadingTest {
public void print(SuperIfc x){
System.out.println("SuperIfc");
}
public void print(SuperClass x){
System.out.println("SuperClass");
}
public void print(SubClass x){
System.out.println("SubClass");
}
public void print(Object x){
System.out.println("Object");
}
public static void main(String[] args) {
OverloadingTest obj = new OverloadingTest();
SuperClass superObj = new SuperClass();
SubClass subObj = new SubClass();
obj.print(superObj);
obj.print(subObj);
obj.print(null);
obj.print((SuperIfc)superObj);
obj.print((SuperIfc)subObj);
obj.print((SuperIfc)null);
/*
* OUTPUT
* SuperClass
* SubClass
* SubClass
* SuperIfc
* SuperIfc
* SuperIfc
*/
}
}
(这解释了null,null)。浮点数的大小写很简单。好的,我想我已经理解了:)所以因为1.2f
被视为浮点数,它只能自动装箱到Float
而不能自动装箱到Double
。但是,如果我将Double
更改为Double
,它会起作用,因为在包装类中不可能使用Double
。