首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java重载: Number,Number;int,Double

Java重载: Number,Number;int,Double
EN

Stack Overflow用户
提问于 2012-06-15 23:18:58
回答 3查看 3.9K关注 0票数 14

再过两天我有个java考试,我想不出这个问题的答案:

代码语言:javascript
复制
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));
 }
}

输出是什么?

答案是:

代码语言:javascript
复制
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方法之间选择...

会很有帮助,如果你们能给我解释一下:)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-15 23:25:22

1.2f不是由Double包装的,它是由Float包装的。因为Float不是Double的子类(它们是Number的不同子类),所以可以使用的最具体的方法签名是foo(Number,Number)

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

票数 18
EN

Stack Overflow用户

发布于 2012-06-15 23:31:20

这里有两个重要的因素。

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

其次,即使您将其更改为1.2,它仍然不是Double。它是一个double。也就是说,它是一个原语,而不是一个对象。现在,Java仍然会愉快地将double传递给需要Double的函数,但在本例中,您给了它两个可以进行的有效转换,从而混淆了它:

  1. 5转换为Integer 1.2转换为5 int作为基元代码,但将1.2转换为Double.

对于哪一个是可取的,没有一个规则。Java会产生一个编译器错误,说明它有一个不明确的函数调用,并迫使您选择您更喜欢的函数(通过手动将它们中的一个或两个包装在对象中)。

顺便说一句,如果您有一个接受(int, double)的方法,就不会有任何歧义:该方法实际上与现有的51.2类型相匹配,因此它将被调用。这是一个事实,这里的一些参数是包装器对象,导致了混乱。

票数 4
EN

Stack Overflow用户

发布于 2014-05-30 14:42:16

通用答案:

代码语言:javascript
复制
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
         */
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11053564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档