当前位置: 首页 > 面试题库 >

这真的比自动装箱要宽吗?

郭元凯
2023-03-14
问题内容

我在参考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)

输出将显示“ Integer”

这到底是怎么回事?我对Java的编译器/字节码解释器一无所知…


问题答案:

在第一种情况下,您正在发生越来越多的转换。在编译的类上运行“ 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),以将原始容器装箱在包装器中。



 类似资料:
  • 问题内容: 为什么第二段代码更快? 问题答案: 自动装箱使用,内部将Integer对象缓存为小整数(默认情况下为-128至127,但是最大值可以使用“ java.lang.Integer.IntegerCache.high”属性进行配置-请参见Integer.valueOf的源代码) ,因此与直接调用不同。因为在调用之前可以快速检查整数值的大小,所以直接调用要快一些(尽管如果您有很多小整数,它会使

  • 本文向大家介绍自动装箱和拆箱?相关面试题,主要包含被问及自动装箱和拆箱?时的应答技巧和注意事项,需要的朋友参考一下 自动装箱是Java 编译器在基本数据类型和对应的对象包装类型之间做的一个转化。 比如:把int转化成 Integer,double转化成 Double,等等。反之就是自动拆箱。 原始类型: boolean,char,byte,short,int,long,float,double 

  • 如果我有一个泛型参数,我通过模式匹配到基元(如 )来解析该参数,那么自动装箱是否比使用自定义包装器类型便宜?例如 对抗 第一种方法是否提供任何性能优势?如果该方法使用代替,这种情况是否相同: ?

  • 问题内容: 两者之间有什么区别。我知道Boxing正在将原始值转换为引用。什么在扩大。还有,应该先进行顺序装箱还是应进行加宽的顺序? 问题答案: 扩展是将变量转换为具有更大类型的变量。 可以使用原始或引用类型进行扩展。 例如 : -> -> 正如JLS所述: 装箱转换(第5.1.7节) [是](可选)后跟加宽的参考转换 资源: JLS-扩展原始转换 JLS-扩大参考转换

  • 有以下代码: 它打印: 12 这个不能编译。为什么?

  • 可以用Java定义自定义自动装箱吗? 在键入函数的参数时,我需要自动将转换为我的类。对于两个参数,我最终编写了四个非常相似的方法: 所以我可以输入: 然而,我认为这对于10个参数(我想做的)变得难以管理;我想我需要写1024个类似的方法。 我正在考虑的另一个解决方案是编写一个方法,例如: 但是我可以键入数字和混合在一起作为参数吗?