31

我在另一个问题的回答中看到了这一点,参考了 Java 规范的缺点:

还有更多的缺点,这是一个微妙的话题。看看这个

public class methodOverloading{
     public static void hello(Integer x){
          System.out.println("Integer");
     }

     public static void hello(long x){
          System.out.println("long");
     }

     public static void main(String[] args){
         int i = 5;
         hello(i);
     }
}

这里将打印“long”(我自己没有检查过),因为编译器选择加宽而不是自动装箱。使用自动装箱时要小心,或者根本不要使用它!

我们确定这实际上是扩大而不是自动装箱的一个例子,还是完全是别的东西?

在我最初的扫描中,我同意这样一种说法,即输出将是“长”的,i因为它被声明为一个原语而不是一个对象。但是,如果你改变了

hello(long x)

hello(Long x)

输出将打印“整数”

这里到底发生了什么?我对java的编译器/字节码解释器一无所知......

4

3 回答 3

16

在第一种情况下,您的转换正在扩大。在编译的类上运行“javap”实用程序(包括 JDK)时可以看到这一点:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   i2l
   4:   invokestatic    #6; //Method hello:(J)V
   7:   return

}

很明显,您会看到 I2L,它是扩展 Integer-To-Long 字节码指令的助记符。请参阅此处的参考。

在另一种情况下,将“long x”替换为对象“Long x”签名,您将在 main 方法中拥有以下代码:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   invokestatic    #6; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   6:   invokestatic    #7; //Method hello:(Ljava/lang/Integer;)V
   9:   return

}

所以你会看到编译器创建了指令 Integer.valueOf(int),将原语装箱到包装器中。

于 2008-08-07T18:18:34.897 回答
5

是的,在测试中尝试一下。您将看到打印出“长”字样。它正在扩大,因为 Java 在选择将其自动装箱为 Integer 之前会选择将 int 扩大为 long,因此选择调用 hello(long) 方法。

编辑:被引用的原始帖子

进一步编辑:第二个选项会打印 Integer 的原因是因为没有“扩大”到更大的基元作为选项,所以它必须将它装箱,因此 Integer 是唯一的选择。此外,java 只会自动装箱到原始类型,因此如果您离开 hello(Long) 并删除 hello(Integer),它会给出编译器错误。

于 2008-08-07T16:36:25.447 回答
3

这个例子的另一个有趣的事情是方法重载。类型扩展和方法重载的组合仅起作用,因为编译器必须决定选择哪种方法。考虑以下示例:

public static void hello(Collection x){
   System.out.println("Collection");
}

public static void hello(List x){
   System.out.println("List");
}

public static void main(String[] args){
   Collection col = new ArrayList();
   hello(col);
}

它不使用 List 的运行时类型,它使用 Collection 的编译时类型,因此打印“Collection”。

我鼓励您阅读Effective Java,它让我看到了 JLS 的一些极端案例。

于 2008-08-07T19:02:29.630 回答