繁体   English   中英

Java重载:数字,数字; INT,双

[英]Java Overloading: Number,Number ; int,Double

在两天内我在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";
 }
 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,Object方法。 但为什么a.foo(5,1.2f); 还调用了Number,Number方法而不是int,Double方法??

但还有一件事可能会有所帮助:如果我在1.2之后删除f ,那么调用是: a.foo(5,1.2); 我得到一个编译器错误,它无法在Number,Numberint,Double Method之间进行选择...

如果你们能向我解释一下,那会非常有帮助:)

1.2f没有被Double包裹,它被Float包裹。 由于Float不是Double的子类(它们是Number不同子类),因此可以使用的最具体的方法签名是foo(Number,Number)

删除f ,默认情况下1.2将被视为double (原语,而不是包装类),可以自动装箱为Double 然而,5也可以自动装箱到Integer ,从而导致模糊。

这里有两个重要因素。

首先, 1.2f不是Double 这是一个Float (int, Double)函数根本不匹配。 (Number, Number)是最合适的。

其次,即使将其更改为1.2它仍然不是Double 这是double 也就是说,它是一个原始的,而不是一个对象。 现在,Java仍然会愉快地将一个double传递给一个想要Double而没有太多抱怨的函数,但在这种情况下,你通过给它两个有效的转换来混淆它:

  1. 转换5到一个Integer ,并转换1.2Double
  2. 5保留为原始int但将1.2转换为Double

对于哪一个更为可取,没有规则。 Java产生编译器错误,它有一个模糊的函数调用,并强制您选择您喜欢哪一个(通过手动将其中一个或两个包装在对象中)。

顺便说一句,如果你有一个方法(int, double)根本就没有歧义:该方法实际上匹配现有的51.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
         */
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM