Skip to the content.

Java基本类型和包装类

先了解下基础,有个大概印象

包装类

下面是java中基本类型和对应的包装类

基本类型 包装类
boolean Boolean
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character

基本类型和包装类的转换

Integer

// 基本类型
int i1 = 12345;
// 基本类型转化为包装类 将基本类型通过 Integer.valueOf方法转换为 包装类
Integer iObj = Integer.valueOf(i1);
// 包装类转化为基本类型 包装类的intValue方法装换为基本类型
int i2 = iObj.intValue();


其他类型也是如此。

装箱

基本类型转换为包装类


从基本类型到包装类。 把基本类型装到包装类中,就是装箱。

拆箱

包装类转换为基本类型


从包装类到基本类型。把包装类中搞出基本类型,就是拆箱。

自动装箱/拆箱

自动装箱

在JAVA SE5之前若要生成一个数值为10的Integer对象,必须new Integer才可。
例如下面代码

Integer i = new Integer(10);


但是在JAVA SE5之后,直接执行如下代码就可生成数值为10的Integer对象

Integer i = 10;

自动拆箱

同样也是JAVA SE5进行的自动拆箱操作。
JAVA SE5之前

Integer i = new Integer(10); // 装箱
int j = i.intValue();		 // 拆箱


JAVA SE5之后

Integer i = 10;  //装箱
int n = i;   //拆箱

源码剖析 自动装箱/拆箱实现

源码

public class Main {
    public static void main(String[] args) {
        Integer i = 10; //装箱操作
        int n = i;		//拆箱操作
    }
}

编译

javac Main.java

反编译

可以看到第13行,实际上调用了Integer.valueOf方法   编译实现了装箱操作 可以看到第16行,实际上调用了Integer.intValue方法  编译实现了拆箱操作

 mac@MacBook-Pro  ~/study/java  javap -c Main
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  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: aload_1
       7: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
      10: istore_2
      11: return
}

包装类.valueOf() 和 new 包装类()

可以看下Integer的实现



	public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }


    public Integer(int value) {
        this.value = value;
    }


看代码
public class Main {
    public static void main(String[] args) {
        System.out.println(new Integer(1000) == 1000);
    }
}

看反编译的代码
mac@MacBook-Pro ~/study/java javap -c Main
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: new           #3                  // class java/lang/Integer
       6: dup
       7: sipush        1000
      10: invokespecial #4                  // Method java/lang/Integer."<init>":(I)V
      13: invokevirtual #5                  // Method java/lang/Integer.intValue:()I  这里是自动拆箱
      16: sipush        1000
      19: if_icmpne     26
      22: iconst_1
      23: goto          27
      26: iconst_0
      27: invokevirtual #6                  // Method java/io/PrintStream.println:(Z)V
      30: return
}

考察IntegerCache

public class Main {
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        Integer c = 200;
        Integer d = 200;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}


image.png
Integer如果在 -128到127之间,可以直接使用内存中的数据。
变量 a b 指向的都是同一个地址。
变量 c d 指向不同的地址。