装箱和拆箱

  • 装箱:把基本类型数据转成对应的包装类对象
  • 拆箱:把包装类对象转成对应的基本数据类型数据
  • 自动装箱:把一个基本类型变量直接赋给对应的包装类变量或 Object 变量
    • 在底层依然是手动装箱,使用的是 Xxx.valueOf() 方法
    • 因此,Object obj = 17; Object[] arr = {"A", 12, 3.14, true};
  • 自动拆箱:把包装类对象直接赋给对应的基本数据类型变量,或者包装类对象与基本数据类型变量使用“==”比较

    • 在底层依然是手动拆箱,使用的是 xxxValue() 方法
    • 因此,switch 语句也支持 byte, short, char, int 对应的包装类

    基本类型包装类
    图 1 基本类型包装类

  • 可以把基本类型的变量近似地当成对象使用,也可以把包装类的实例近似地当成基本类型的变量使用
  • 八大基本数据类型的包装类都都是最终类不可变类(对应的储存数值的成员变量 value 值使用 private final 修饰)
  • Byte、Short、Integer、Long、Float、Double、BigDecimal、BigInteger 类都是 Number 抽象类的子类,都是 Comparable 接口的实现类
  1. Integer intObj1 = new Integer(123);
  2. Integer intObj2 = Integer.valueOf(123); // 推荐,带有缓存
  3. int num3 = intObj1.intValue(); // int num3 = new Integer(123);
  4. Integer intObj4 = 123; // 底层 Integer intObj4 = Integer.valueOf(123)
  5. int num5 = intObj4; // 底层 int num5 = intObj4.intValue()
  6. intObj4 == 123; // true,底层 intObj4.intValue() == 123
  7. Object boolObj = true;
  8. if (boolObj instanceof Boolean) {
  9. boolean b = (Boolean)boolObj;
  10. System.out.println(b);
  11. }

包装类的常用操作方法

  • 包装类中 public static final 修饰的字段:MIN_VALUEMAX_VALUESIZE(在内存中存储占的比特位数)、TYPE(对应基本类型的 Class 对象)

  • 包装类的构造器,用于创建对应的包装类对象(xxx 类型的包装类 Xxx)

    • Xxx(xxx value):a. 装箱,如 Integer(int value) Boolean(boolean value)
    • Xxx(String str):f. 字符串 → 包装类
      • Character 类没有此构造器
      • Boolean(String str) // 如果 str 不为 null 且在忽略大小写时等于 "true",则创建一个表示 true 值的 Boolean 对象,否则创建一个表示 false 值的 Boolean 对象
      • 当该字符串不能转换为适当格式时,抛出异常 NumberFormatException
  • Short、Integer、Long、Float 和 Double 类中常用的静态方法

    • xxx sum(xxx a, xxx b):将两个数相加
    • xxx min(xxx a, xxx b):返回两个数的较小值, Math.min
    • xxx max(xxx a, xxx b):返回两个数的较大值, Math.max
    • int compare(xxx a, xxx b):比较两个数值,a 小于、等于或大于 b 则分别返回 -1、0 或 1
    • xxx getXxx(String nm, Xxx val):获取指定名称的系统属性值,如果没有则返回 val
  • 包装类、基本类型、字符串之间的转换
Xxx类中的类方法方法说明
Xxx valueOf(xxx value)a. 装箱(推荐,带有缓存)
Xxx valueOf(String s)f. 字符串 → 包装类
String toString(xxx value)c. 基本类型 → 字符串
xxx parseXxx(String s)d. 字符串 → 基本数据(Character 除外)
实例方法方法说明
xxx xxxValue()b. 拆箱(Number 类)
char charValue()b. 拆箱
boolean booleanValue()b. 拆箱
String toString()e. 包装类 → 字符串
boolean equals(Object obj)g. 判断包装类对象的值是否相等
compareTo(T o)f. 该对象小于、等于或大于指定对象则分别返回 -1、0 或 1
  • c.基本类型 → 字符串:String String.valueOf(xxx value); // String 类中的类方法

    包装类转换
    图 2 包装类转换

包装类中的缓存设计(享元模式)

  • Byte、Short、Integer、Long:使用 cache 数组默认缓存了 -128~127 之间的整数自动装箱成的包装类对象
  • Character:使用 cache 数组默认缓存了 0~127 之间的整数自动装箱成的 Character 类对象

把一个在缓存区间内的整数通过 valueOf(xxx value) 装箱成包装类对象时,该对象引用 cache 数组的同一个数组元素

  1. public static Integer valueOf(int i) {
  2. if (i >= IntegerCache.low && i <= IntegerCache.high)
  3. return IntegerCache.cache[i + (-IntegerCache.low)];
  4. return new Integer(i);
  5. }
  6. // 通过 new 创建的包装类对象不是
  7. public Integer(int value) {
  8. this.value = value;
  9. }