然后在==运算符上加宽Java框

L4z*_*4zy 4 java

Number n = 10; 
int i = 10;
System.out.println(n == i);
Run Code Online (Sandbox Code Playgroud)

基于"你可以加箱然后加宽".为什么上面的代码会产生编译时错误?我的猜测是,如果将第一个盒装到Integer并扩大到Number,结果将始终为false.在比较基元和对象时,有任何指定==运算符的规范吗?将始终尝试执行拆箱,并且必然会扩大?

chr*_*ke- 9

根据JLS,==盒装和非盒装值之间的比较会导致取消装箱转换,而不是相反(或者您使用引用相等,而不是值相等).编译器无法取消打包平面Number; Number本身不是"可转换为数字类型".

Java 7编译器似乎很聪明.此版本的程序集输出以及将比较移动到private方法中的版本完全忽略声明的类型Number,并且一切正常.作出这样的方法public,并且行为是规定:转换不是将发生拆箱列出的类型之一,而编译器盒10Integer和基准电压进行比较,这意味着,如果你试图使用Integer.valueOf(10),你会得到true的范围-128..127,如果你使用其他任何东西(另一个宽度new Integer(10)),你会得到false.

您的代码输出(请注意,Number无处可见,并且您将根据第18行中的引用相等性进行比较;尝试使用L或转换为short):

public static void main(java.lang.String[]);
  Code:
   0: bipush        10
   2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   5: astore_1      
   6: bipush        10
   8: istore_2      
   9: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
  12: aload_1       
  13: bipush        10
  15: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  18: if_acmpne     25
  21: iconst_1      
  22: goto          26
  25: iconst_0      
  26: invokevirtual #4                  // Method java/io/PrintStream.println:(Z)V
  29: return
Run Code Online (Sandbox Code Playgroud)

阻止优化的版本:

public class Test
{
    public static void main(String[] args)
    {
        Number n = new Integer(10);
        compare(n);
    }

    public static void compare(Number n)
    {
        int i=10;
        System.out.println(n == 10);
    }
}
Run Code Online (Sandbox Code Playgroud)

部件; 请注意,您仍然在第12行获得参考比较:

public static void main(java.lang.String[]);
  Code:
   0: new           #2                  // class java/lang/Integer
   3: dup           
   4: bipush        10
   6: invokespecial #3                  // Method java/lang/Integer."<init>":(I)V
   9: astore_1      
  10: aload_1       
  11: invokestatic  #4                  // Method compare:(Ljava/lang/Number;)V
  14: return        

public static void compare(java.lang.Number);
  Code:
   0: bipush        10
   2: istore_1      
   3: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
   6: aload_0       
   7: bipush        10
   9: invokestatic  #6                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  12: if_acmpne     19
  15: iconst_1      
  16: goto          20
  19: iconst_0      
  20: invokevirtual #7                  // Method java/io/PrintStream.println:(Z)V
  23: return
Run Code Online (Sandbox Code Playgroud)

  • -1这不是查看字节代码时发生的情况. (3认同)