美文网首页
Java自动装箱和拆箱

Java自动装箱和拆箱

作者: gczxbb | 来源:发表于2019-07-22 14:03 被阅读0次

一、基本类型

基本类型 位数 字节 包装器
byte 8位 1 Byte
boolean true/false 1 Boolean
char 16位,存储Unicode码 2 Character
short 16位 2 Short
int 32位 4 Integer
float 32位 4 Float
long 64位 8 Long
double 64位 8 Double

二、自动装箱和拆箱

装箱,将基本数据类型转换成包装器类型。拆箱,将包装器类型转换成基本数据类型,拆箱和装箱是编译器自动实现转换。
1,定义一个Integer类型赋值。

Integer a =  100;//装箱
int b = a;//拆箱

基本类型赋值Integer类引用,自动装箱,该过程调用Integer类valueOf()方法,(反编译查看)。

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

-128~127范围,使用缓存Integer对象,对于该范围int的相同基本数字装箱的Integer是同一地址对象。
其他范围创建一个Integer对象,内部value赋值。
将Integer类型赋值基本类型,自动拆箱,该过程调用Integer类intValue()方法。

public int intValue() {
    return value;
}

返回内部int类型value数据,赋值给int基本变量类型。
2,Integer类型列表添加元素。

List<Integer> list = new ArrayList<>();
list.add(10);//装箱
int value = list.get(0);//拆箱

List的add()方法,添加一个基本类型,自动装箱,从List中获取一个元素(Integer),赋值给基本int类型,自动拆箱。
3,Integer类型Map添加元素。

HashMap<Integer,String> map = new HashMap<>(Integer,String);
map.put(10, "test");//装箱
map.get(10);//拆箱

HashMap的key是Integer类型,put()方法和get()方法,添加/获取kv,基本类型参数key自动装箱,new创建对象,频繁装箱影响内存和性能。
4,反编译,初始化a和b变量代码,通过javap反编译查看。

public static void main(java.lang.String[]);
    Code:
       0: bipush        100
       2: invokestatic  #16     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: aload_1
       7: invokevirtual #22      // Method java/lang/Integer.intValue:()I
      10: istore_2
      11: return
    LineNumberTable:
      line 8: 0
      line 9: 6
      line 10: 11
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      12     0  args   [Ljava/lang/String;
          6       6     1     a   Ljava/lang/Integer;
         11       1     2     b   I

编译class字节码,invokestatic,Integer类的valueOf()和intValue()方法,自动装箱和拆箱。

三、运算

 int a = 120;
 Integer b = 120;
 System.out.println(a == b);//true
 
 Integer c = 120;
 Integer d = 120;
 System.out.println(c == d);//true
 
 c = 200;
 d = 200;
 System.out.println(c == d);//false

 Double e = 10.0;
 Double f = 10.0;
 System.out.println(e == f);//false

1,基本类型和包装器类型运算时,按基本类型,b是Integer类型,赋值时自动装箱,和int基本类型比较,b自动拆箱。
2,c和d都是Integer类型,(==比较内存地址),赋值基本类型,装箱,值在-128~127范围,Integer缓存对象,数值相同,自动装箱对象是同一个,地址相同。
3,c和d赋值基本类型,大于127范围,分别new装箱对象,地址不同。
4,Double类赋值基本类型时,自动装箱,==比较地址,装箱调用valueOf()方法。

public static Double valueOf(double d) {
    return new Double(d);
}

创建Double对象,未使用缓存,所以两个new对象==地址不等,(与Integer类不同)。

四、总结

当一个包装类和基本数据类型运算(==、+、-、*、/、>、<)时,将包装类进行拆箱,按照基本类型进行运算。

赋值运算时,根据变量类型(基本类型和包装类类型),自动装箱或拆箱。

equals()比较时,装箱操作。

装箱,创建对象。


任重而道远

相关文章

网友评论

      本文标题:Java自动装箱和拆箱

      本文链接:https://www.haomeiwen.com/subject/mmailctx.html