我看到这个 回答另一个问题, ,在提到的缺点的规格:

有更多的缺点,这是一个微妙的主题。检查 出:

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);
     }
}

这里的"长"将印刷(没有检查它自己的),因为这个编译器选择的扩大超过自动拳击。谨慎使用自动装箱或者不要使用它。

我们确信,这实际上是一个例子的扩大而不是自动装箱,或者是完全不同的东西?

在我的初步扫描,我会同意所作的发言,输出会被"长时间"的基础上 i 被宣布为一种原始的和不对象。但是,如果你改变了

hello(long x)

hello(Long x)

输出将打印"Integer"

什么真在这里?我什么都不知道有关编译/口译码java...

有帮助吗?

解决方案

在第一种情况,你有一个扩大的转换情况的发生。这可能是看到当runinng的"javap"实用程序(包括w/the JAVA)在编制课:

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,这是记忆,为日益扩大的整数长码指令。参见参考 在这里,.

而在其他情况下,取代"长x"目的"长x"签名,你就会有这样的代码,在主要方法:

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

}

所以你看到的编译器创造了指令整数。值(int),以箱的原始内部的包装。

其他提示

是的是,尝试在试验。你会看到"长时间"印刷。它正在扩大,因为Java会选择以扩大int成长之前,它选择autobox到整数,所以你好(长期)的方法是选择被称为。

编辑: 原来的职位是引用.

进一步的编辑:这的原因第二项选择将打印的整数是因为没有"扩大"到一个更大的原始作为一个选项,因此它必须把它装箱,因此整数是唯一的选择。此外,java只会autobox原型,因此它将得到一个编译器错误如果你离开的你好(长)和拆除你好(Integer)。

另一个有趣的事情跟这个例子是方法过载。该组合的类型扩大和方法载只有工作,因为编译器已经做出决定哪一种方法选择。考虑下面的例子:

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);
}

它不使用运行时间类型,这是名单,它使用的编写时间类型是收集和由此印"集合"。

我鼓励你来读 有效的Java, ,它打开了我的眼睛的某个角落的案件的捷尔思.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top