包装类型及自动装箱

89 阅读2分钟

基本类型

image.png

基本类型转换

小可直接转大、大转小会失去精度

包装类型

image.png

基本类型与包装类型的区别

  • 包装类型使用new关键字分配存储空间,而基本类型只在栈内存中直接引用

  • 包装类型可以为null,而基本类型不可以,数据库的查询结果可能为null,如果使用基本类型的话,因为要自动拆箱 (将包装类型转为基本类型,比如说把 Integer 对象转换成int值),就会抛出 NullPointerException的异常。

  • 包装类型可用于泛型,而基本类型不可以。泛型不能使用基本类型,因为使用基本类型时会编译出错。

自动拆/装箱

自动拆装箱主要应对基本类型与包装类型的相互转换问题。

  • 自动装箱:过程是通过调用包装类的valueOf()方法实现的,因此只需Integer i = 10这样的语句就能实现基本数据类型转换成包装类,通过反编译可知,这是因为JVM为我们执行了Integer i = Integer.valueOf(10)这样的操作。
    public void test1() {
        Integer a = 10;       //等价于 Integer a = Integer.valueOf(10);       
    }
  • 自动拆箱:每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()doubleValue()等转型方法。自动拆箱过程是通过调用包装类的 xxxValue()方法实现的
   public void test1() {
       int a = new Integer(10);      //等价于int a = new Integer(10).intValue();
   }

例子

 Integer i1 = 100;
 Integer i2 = 100;
 Integer i3 = 200;
 Integer i4 = 200;
 System.out.println(i1==i2);      // true
 System.out.println(i3==i4);      // false

Integer a1 = 1;
Integer b1 = 1;
Integer c1 = 300;
Integer d1 = 300;
System.out.println(a1==b1);       //true
System.out.println(c1==d1);       //false
 
Integer a2 = Integer.valueOf(1);
Integer b2 = Integer.valueOf(1);
Integer c2 = Integer.valueOf(300);
Integer d2 = Integer.valueOf(300);
System.out.println(a2==b2);       //true
System.out.println(c2==d2);       //false
 
Integer a3 = new Integer(1);      // 构造器传值,并没有调用valueOf方法,所以也没有缓冲池
Integer b3 = new Integer(1);
Integer c3 = new Integer(300);
Integer d3 = new Integer(300);
System.out.println(a3==b3);       //false
System.out.println(c3==d3);      //false

-   除了 Float 和 Double 之外,其他六个包装类都有常量缓存池
    拿 Integer 来举例子,Integer类内部中内置了 256个Integer类型数据,当使用的数据范围在-128 ~ 127之间时,
    会直接返回常量池中数据的引用,超过这个范围则才会创建对象。

缓存池

image.png

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);
}

-   IntegerCache.cache是一个数组,范围是[-128~127],
    如果传进来的数值在这个范围内,就直接返回这个数组里的内容。如果超出这个范围,就返回一个新建对象。

类型比较

image.png

String类型转换

int a = 3; 
String s = String.valueOf(a);  // 基本数据类型到String类

String s = "12"; 
int a = Integer.parseInt(s);   // String类到基本数据类型

String s = "12"; 
Integer a = new Integer(s);  //  String类到包装类