这段Java代码是如何工作的?

3

我有这段代码。

 class NumberMachine { 
   public static void main(String [] args) { 
     Integer wi1 = new Integer("420"); 
     int i = 101; 
     Integer wi2 = i*420/101; 

     if(wi1 == wi2)
       System.out.print(" =="); 
     if(wi1.equals(wi2))
       System.out.print(" equal"); 
     float f = 1.23f; 
     new NumberMachine().printIt(f); 
  } 

  void printIt(Float f) { 
    System.out.println(" Float"); 
  } 

  void printIt(double d) { 
    System.out.println(" double"); 
  } 
} 

为什么结果是“等于双精度”,而不是“等于浮点数”?
3个回答

11

为了决定应该调用哪个方法,编译器会按照以下列表进行检查,详见JLS #5.3JLS #15.12.2

  • 标识转换 (§5.1.1)
  • 扩展基本类型转换 (§5.1.2) ==> 在此处适用 printIt(double)
  • 扩展引用类型转换 (§5.1.5)
  • 装箱转换 (§5.1.7),可选择后跟扩展引用类型转换 ==> 如果没有printIt(double),则会调用printIt(Float)
  • 拆箱转换 (§5.1.8),可选择后跟扩展基本类型转换。

1
这样做的原因是扩宽转换(widening)装箱(boxing)更早存在,所以如果不按照这个顺序进行,旧代码的行为可能会发生改变。 - Keppil
@Keppil 当然可以-它们实际上在JLS#15.12.2.1中提到了: 这保证了Java SE 5.0之前在Java编程语言中有效的任何调用都不会由于引入可变性参数方法、隐式装箱和/或拆箱而被视为模棱两可。 - assylias

2

因为 扩宽 (浮点数到双精度浮点数) 比 装箱 更快


"while method resolution..." 这句话似乎缺少一些词语,请您重新表述一下。 - Graham Borland

0

printIt(Float f) 接受 Float 对象,而 printIt(double d) 接受原始类型 double。

因此,第二个 printIt 函数被调用时,将 float 强制转换为 double。

请参阅 http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Float.html

你可以像这样调用第一个函数:

Float f = new Float(5.0);
printIt(f);

“printIt(Float f)接受Float对象,而不是原始类型float。”=> 这并不完全准确 - 如果没有printIt(double)方法,程序将打印“equals Float”。 - assylias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接