美文网首页JAVAJava
[Java]浅谈Java中的包装器类型以及自动装箱与拆箱

[Java]浅谈Java中的包装器类型以及自动装箱与拆箱

作者: AbstractCulture | 来源:发表于2020-10-27 01:39 被阅读0次

    什么是对象包装器

    这得从Java的八大基础数据类型讲起,Java作为一种强类型的语言,它为每个变量声明了一种类型,其中一共有8种基本类型,它们分别是:

    基本类型 存储所需大小 对象包装器
    int 4字节 Integer
    short 2字节 Short
    long 8字节 Long
    byte 1字节 Byte
    float 4字节 Float
    double 8字节 Double
    char 2字节 Character
    boolean 根据JVM的编译行为会有不同的结果(1/4) Boolean

    注意:使用float和double进行运算时,可能会产生误差。金融相关的数据推荐使用BigDecimal。这是由于二进制系统中无法精确地表示分数所导致的

    基础类型的内存分配策略

    这里我们从阿里巴巴的开发手册中来切入:

    对于Integer var = ? 在-128至127 范围内的赋值,Integer 对象是在 IntegerCache.cache 产 生,会复用已有对象。
    这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数 据,都会在堆上产生,并不会复用已有对象,
    这是一个大坑,推荐使用 equals方法进行判断。
    由此可见,常用的一些常量,会在栈中进行存储,超出一定的界限后,这些数值存储在堆中。

    Java使用了基本类型来让一些常用的数值可以存储在栈中,从而让整体的内存消耗更加小巧,如果有多个参数的值都是100,那么统一指向100这个数字在JVM栈中的地址即可。但是编程中很多时候,我们需要这些数字具备对象的能力,比如说我从序列化的JSON中得到了一个数值,它的类型是String->"100",那么有没有办法让它变成int呢?
    为了解决这些问题,Java推出了包装器类型。

    使用对象包装器时,你需要注意的几个点

    • 对象包装器是不可变的。对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。
      如果需要理解这个思想,你可以执行这段代码
    public class IntegerTest {
        public static void main(String[] args) {
            Integer two = Integer.valueOf(2);
            change(two);
            System.out.println(two);
        }
    
    
        public static void change(Integer integer) {
            integer = integer + 1;
        }
    }
    
    • 对象包装器声明为final,因此不可以被继承
    • 在定义集合的时候,不支持基本类型,可以使用包装器
    • 相对于基础类型来说,包装器往往意味着更多的空间
    • 用equals去比较对象包装器的值,而不是==
    • 对于不可预期值的包装器值,最好加上空值判断

    自动装箱与拆箱

    • 自动装箱: 编译器自动将基本类型转化成包装器类型的行为

      box.png
    • 自动拆箱: 编译器自动将包装器类型转化成基本类型的行为

      unweave.png

    自动拆箱引发的NPE问题

    包装器类可以允许引用为null,所以自动拆箱有可能会抛出一个NullPointerException

    • 拆箱时引发的空指针异常
            Integer integer = null;
            System.out.println(2*integer);
    

    integer.intValue(); 这个方法不允许integer为null

    包装器类型的升级

    如果在一个计算中混用了Integer和Double类型,Integer值就会拆箱,提示为Double,再进行装箱。

            Integer integer = 1;
            Double douNum = 2.0;
            System.out.println(integer*douNum);
    

    相关文章

      网友评论

        本文标题:[Java]浅谈Java中的包装器类型以及自动装箱与拆箱

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