Java重载 - long和float

时间:2017-05-05 04:52:40

标签: java overloading

我试图理解java重载规则。一切似乎都很好,除了以下,

public static void main(String[] args) {
    long aLong = 123L;        
    foo(aLong);
}

private static void foo(double aDouble) {
    System.out.println("Foo aDouble");
}

private static void foo(Long aWrapperLong) {
    System.out.println("Foo Wrapper Long");
}

private static void foo(int anInt) {
    System.out.println("Foo Int");
}

private static void foo(float aFloat) {
    System.out.println("Foo Float");
}

为什么通话会解析为foo(float aFloat)。我从JLS了解以下内容,

  

此步骤使用方法的名称和参数的类型   表达式,用于查找既可访问又适用的方法   可能存在多于一种这样的方法,在这种情况下最多   选择具体的一个。

我故意在这里使用Wrapper Long而不是原始的long。长度为64位的原始长度不会以foo(double aDouble)结尾,而是32位浮点foo(float aFloat)

问题Why does Java implicitly (without cast) convert a `long` to a `float`?进一步澄清了这个问题的答案。

3 个答案:

答案 0 :(得分:15)

这是因为JLS #15中的“最具体”规则,后者又指JLS #4.10,后者又指#4.10.1,其中指出:

  

以下规则定义了基元类型之间的直接超类型关系:

     
      
  • double> 1 float

  •   
  • float> 1 long

  •   
  • long> 1 int

  •   
  • int> 1 char

  •   
  • int> 1 short

  •   
  • 短> 1 byte

  •   

其中“S> 1 T”表示“T是S的直接子类型”,根据本节紧接的JLS#4.10。

所以在这种情况下,如果没有long上的直接匹配,并且在查看自动装箱之前,编译器会根据上述规则选择最近的可用超类型,即float

答案 1 :(得分:4)

转换具有优先规则。 它将选择加宽而不是拳击

因此,在这种情况下,编译器搜索的方法可以接受比长原始数据类型更大(最接近可能更大)的参数作为参数,即float。

如果从发布的示例中删除方法 foo(double aDouble) foo(float aFloat),则编译器将执行装箱,选择 foo(Long aWrapperLong)

答案 2 :(得分:2)

在自动装箱以进行重载之前,扩展优先。 从一开始就没有在java中引入原语的包装类(Integer,Long& so等),因为java支持向后兼容性,它应该执行在较新版本中以相同方式在一个java版本中编写的代码。