这与自动装箱相比真的扩大了吗? [英] Is this really widening vs autoboxing?

查看:34
本文介绍了这与自动装箱相比真的扩大了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在有关另一个问题的答案中看到了这一点,其中提到了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆