Java-automatic unboxing and automatic boxing

Packaging

: Each basic data type corresponds to a reference data type
Insert picture description here
. The basic data types in Java have no methods and attributes, and the wrapper class is to allow these to have methods and attributes to achieve object-oriented interaction.
The difference between basic data types and packaging classes: Basic data types are used for calculations, and packaging classes provide methods
Insert picture description here

public class Test4 {
    
    
    public static void main(String[] args) {
    
    
        Integer a=new Integer(10);
        // 需要将一个字符串转成 整型进行计算
        Integer b=Integer.parseInt("10");
        System.out.println(a+b); // Integer.intValue 自动拆箱
        System.out.println(a.intValue()+b.intValue());
        Integer c=10;//Integer.valueOf  自动装箱
        Integer c1=Integer.valueOf(10);
        System.out.println(c);
        System.out.println(c1);
        System.out.println(Integer.valueOf(10).intValue());
    }
}
20
20
10
10
10
  • Auto-boxing:
    The Integer.valueOf method is called when assigning a literal value to the packaging type
  • Automatic unboxing
    Integer.intValue is called when the literal is taken out of the package type for calculation. Automatic unboxing

Decompile demo:

public class Hello{
    
    
  public static void main(String[] args) {
    
    
  	//0: new           #2                  // class java/lang/Integer
  	//invokespecial #3                  // Method java/lang/Integer."<init>":(I)V
    Integer a=new Integer(10);
    // bipush        20
    int b=20;
    //invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    // 通过字面量来赋值 JVM 会自动调用  Integer.valueOf
    Integer c=30;
    // invokevirtual #6                  // Method java/lang/Integer.intValue:()I
    //使用的时候自动调用Integer.intValue
    System.out.println(a+10);
    System.out.println(b+10);
    //invokevirtual #6                  // Method java/lang/Integer.intValue:()I
    System.out.println(c+10);
  }
}
C:\Users\86180\Desktop>javap -c Hello
Compiled from "Hello.java"
public class Hello {
    
    
  public Hello();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  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: bipush        20
      12: istore_2
      13: bipush        30
      15: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      18: astore_3
      19: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      22: aload_1
      23: invokevirtual #6                  // Method java/lang/Integer.intValue:()I
      26: bipush        10
      28: iadd
      29: invokevirtual #7                  // Method java/io/PrintStream.println:(I)V
      32: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      35: iload_2
      36: bipush        10
      38: iadd
      39: invokevirtual #7                  // Method java/io/PrintStream.println:(I)V
      42: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      45: aload_3
      46: invokevirtual #6                  // Method java/lang/Integer.intValue:()I
      49: bipush        10
      51: iadd
      52: invokevirtual #7                  // Method java/io/PrintStream.println:(I)V
      55: return
}

important point:

public class Test4 {
    
    
    public static void main(String[] args) {
    
    
        int a=10; // 保存在栈
        int b=10;
        Integer x=10;// 自动装箱  保存在堆
        Integer y=10;
        Integer z=new Integer(10);// 保存在堆
        Integer z1=new Integer(10);
        System.out.println(a==b);
        System.out.println(a==x); //== 是一个运算符 自动拆箱  因此是true
        System.out.println(x==z);//比较的是内存地址 因此是false
        System.out.println(z==z1);//比较的是内存地址 因此是false
        System.out.println(x==y);//关键! 为true
        Integer m=200;
        Integer n=200;
        System.out.println(m==n);//这时候变成了false
    }
}
true
true
false
false
true
false

Why x==yis truebut m==nis falseit?
This is because of the Integer source code:

// 所有的整数类型都是这样
            public static Integer valueOf(int i) {
    
    
                // 如果字面量在 -128 ~ 127 之间直接取值   byte
                if (i >= IntegerCache.low && i <= IntegerCache.high)
                    return IntegerCache.cache[i + (-IntegerCache.low)];
                // 重新申请内存空间
                return new Integer(i);
            }

In fact, the Long type is the same:

            public static Long valueOf(long l) {
    
    
                final int offset = 128;
                if (l >= -128 && l <= 127) {
    
     // will cache
                    return LongCache.cache[(int)l + offset];
                }
                return new Long(l);
            }

But Float is not

public class Test4 {
    
    
    public static void main(String[] args) {
    
    
        Float a=10.7F;
        Float b=10.7F;
        float c=10.7f;
        System.out.println(a==b);
        System.out.println(a==c);
    }
}
false
true

Can be seen that a==bas is false, a==cis true
because the source code Oh Float, valueOf method returns an object, a and b so that different addresses, since this is false:

        // 直接new 的
        public static Float valueOf(float f) {
    
    
            return new Float(f);
        }

In a==cthe process, a is automatically unboxed, and the comparison is literal, so it is true.

Guess you like

Origin blog.csdn.net/qq_44371305/article/details/113541466