这与自动装箱相比真的扩大了吗? [英] Is this really widening vs autoboxing?
问题描述
我在有关另一个问题的答案中看到了这一点,其中提到了Java规范的缺点:
I saw this in an answer to another question, in reference to shortcomings of the Java spec:
还有更多缺点,这是一个微妙的话题.检查此:
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);
}
}
长"字表示会被打印(我自己没有检查过),因为编译器选择加宽而不是自动装箱.使用自动装箱时要小心,否则请不要使用它!
Here "long" would be printed (haven't checked it myself), because the compiler chooses widening over auto-boxing. Be careful when using auto-boxing or don't use it at all!
我们确定这实际上是加宽而不是自动装箱的示例,还是完全其他的东西?
在我的初始扫描中,我同意输出为长"输出的陈述.基于 i
被声明为原始而不是对象.但是,如果您更改了
On my initial scanning, I would agree with the statement that the output would be "long" on the basis of i
being declared as a primitive and not an object. However, if you changed
hello(long x)
到
hello(Long x)
输出将显示"Integer"
the output would print "Integer"
这到底是怎么回事?我对Java的编译器/字节码解释器一无所知...
What's really going on here? I know nothing about the compilers/bytecode interpreters for java...
推荐答案
在第一种情况下,转换范围不断扩大.在编译的类上运行"javap"实用程序(包含在JDK中)时,可以看到以下内容:
In the first case, you have a widening conversion happening. This can be see when runinng the "javap" utility program (included w/ the JDK), on the compiled class:
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字节码指令的助记符.请参见此处.
Clearly, you see the I2L, which is the mnemonic for the widening Integer-To-Long bytecode instruction. See reference here.
在另一种情况下,将"long x"替换为对象"Long x"签名,您将在main方法中使用以下代码:
And in the other case, replacing the "long x" with the object "Long x" signature, you'll have this code in the main method:
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)指令,以将原始容器装箱在包装器中.
So you see the compiler has created the instruction Integer.valueOf(int), to box the primitive inside the wrapper.
这篇关于这与自动装箱相比真的扩大了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!