【自动装箱】Java自动装箱、自动拆箱

Java中集合只允许存储引用数据类型,那么 int char double等基础数据类型,如何存储在集合里呢?Java在JDK1.5版本以后推出了自动装箱、自动拆箱操作,那么什么是自动装箱呢,下面我们举两个例子看:

【自动装箱】

手动装箱示例: 先声明基础数据类型 int,再声明包装类 Integer 把int包装到Integer 再往list集合中add

int x = 90;                        //声明基础数据类型变量
Integer integer = new Integer(x);  //声明Integer包装类 把int类型的x变量包装到Integer中
ArrayList list = new Arraylist;    //创建ArrayList集合
list.add(integer);                 //将Integer包装类添加到list集合中(这种手动把int装到list里的操作,是比较麻烦的 所以后面推出了 自动装箱)
System.out.print(list);            //输出list集合对象(也可以写成 list.toString(),输出的原理是调用了重写的toString方法)

自动装箱示例

int i = 99;                 //声明基础数据类型int变量
ArrayList list = new ArrayList();
list.add(i);                //触发自动装箱,int类型自动转换成 Integer 
System.out.println(list);

如上所示就是集合中的自动装箱,将基础数据类型 装箱成了包装类;

自动装箱:就是将基础数据类型 自动转化为包装类;

各基础数据类型对应的包装类为(注意Java中严格区分大小写):

byte      ->Byte

char      ->Character

short     ->Short

int         ->Integer

long      ->Long

float      ->Float

double  ->Double

boolean->Boolean

   

【自动拆箱】

那么什么叫自动拆箱呢?再接着看两个例子

public class Main{
    public static void main(String[] args){
        Integer int1 = 50;
        Integer int2 = 50;
        Integer int3 = 500;
        Integer int4 = 500;

        System.out.println(int1 == int2);        
        System.out.println(int3 == int4);
    }
}

以上代码 输出的结果 : 第一行为 true 第二行为 false。

那么同样是 == ,为什么会出现这种情况呢?

首先,“ == ” 与 .equals()方法的区别我们需要知道, 通常情况下"==" 比较的是两个对象的地址值是否相同,.equals()方法则是比较 值本身 是否相同。

我们进入Integer类进行查看,发现编译器最终会调用传int参数的ValueOf方法

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

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
        //.........
        //其中代码不做描述,如想看详细 可以自行查阅源码
        }
}

简单描述,IntegerCache把-128到 127之间的数 ,定义成了常量。

那这段代码的意思为,如果值在-128到127之间 则返回这个常量值,如果在-128-127之外,则new Integer 新创建一个Integer类型的对象出来。

因此可以得出 int1 == int2 为true ,因为是常量间的比较(常量是不可变的,在代码运行初即执行,静态方法 常量 都会被初始化到静态方法区,不在堆、栈中体现)

而 int3 == int4 为false ,因为不在-128到127之间,所以是新new的Integer对象,此处 “== ” 为判断地址值是否相等,故结果为 false。

接下来做一段练习

public static void main(String[] args){
    Integer int1 = 3;
    Integer int2 = 3;
    Integer int3 = 6;
    int int4 = 20;
    int int5 = 20;
    Integer integer6 = new Integer(20);
    Integer integer7 = new Integer(20);
    Integer integer8 = new Integer(3);

    System.out.println(int3 == (int1 + int2));//true
    System.out.println(int3.equals(int1+int2));//true
    System.out.println(int4 == int5);//true
    System.out.println(integer6 == int4);//true
    System.out.println(integer6 == integer7);//false
    System.out.println(integer8 == int1);//false
    
}

可以看到最后两行输出结果为 false

第4行 Integer6 == int4,编译器自动调用了 自动拆箱,把Integer6 拆成了int 类型去比较,因此比较的是值,返回 true

第5行 integer6 == integer7 为false,是因为== 比较的是 地址值,而 integer6 和integer7 都是新 new的对象,地址值肯定不同,所以为 false

第6行 integer8 == int1 为false,同理 integer8 为new的对象 int1为一个常量 ,地址值也是不同,所以为false。

以上就是自动装箱 与 自动拆箱的简单解析了。

如有错误请留言纠正 ,谢谢!

你可能感兴趣的:(Java基础,java,开发语言,jvm)