And*_*ndy 28 java primitive autoboxing
我在回答另一个问题时看到了这一点,参考了Java规范的缺点:
还有更多的缺点,这是一个微妙的话题.看看这个:
Run Code Online (Sandbox Code Playgroud)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)
Run Code Online (Sandbox Code Playgroud)
至
hello(Long x)
Run Code Online (Sandbox Code Playgroud)
输出将打印"整数"
这里到底发生了什么?我对java的编译器/字节码解释器一无所知...
Cam*_*pka 13
在第一种情况下,您正在进行扩大转换.在编译的类上运行"javap"实用程序(包含w/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
}
Run Code Online (Sandbox Code Playgroud)
显然,你会看到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
}
Run Code Online (Sandbox Code Playgroud)
所以你看到编译器创建了指令Integer.valueOf(int),用于在包装器中包装原语.