Java基础知识点3——关于自动装箱和自动拆箱机制

在介绍自动装箱和自动拆箱之前,我们要先了解概念:基本数据类型、包装类和常量池。

1、基本数据类型

Java基本数据类型:有8种,分别是byte(字节)、short(短整型)、int(整型)、long(长整型)、float(浮点型)、double(双精度浮点型)、boolean(布尔类型)、char(字符型)。

基本数据类型字节位数取值范围默认值
byte18-128~1270
short216-32768 ~ 327670
int432-2147483648 ~ 21474836470
long864-9223372036854775808 ~ 92233720368547758070L
float4321.4E-45 ~ 3.4028235E380f
double8644.9E-324 ~ 1.7976931348623157E3080d
boolean1——true、falsefalse
char2160 ~ 65535‘u0000’

2、包装类

包装类:作为面向对象语言,有些情况下不能直接对基本数据类型的数据进行处理,为了使基本类型可以像对象一样操作,所以Java语言将基本数据类型包装起来,形成了对应的包装类,对应关系如下表。

基本数据类型对应包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
charCharacter

3、自动装箱和自动拆箱

那么,这两种类型如何转换呢?Java的自动装箱和自动拆箱机制实现了基本数据类型与包装类型的自动转换,在使用到的时候,无需我们人工进行转换操作。

(1)自动装箱

Java自动将基本数据类型转换为包装类型,也就是int→Integer,实际上是调用了方法Integer.valueOf(int)。

public static void main (String[] args) {
      // 创建Integer类型的对象i1时,我们可以直接写60(基本数据类型)
      // 这时会发生自动装箱,将基本数据类型转换为Integer
      // 相当于 Integer i1 = Integer.valueOf(i1);   
      Integer i1 = 60;
}

(2)自动拆箱

Java自动将包装类型转换为基本数据类型,也就是Integer→int,实际上是调用了方法Integer.intValue()。

(3)什么时候发生自动装拆箱

① 赋值操作:在包装类型和基本数据类型之间进行赋值操作时,会发生自动拆装箱。

public static void main (String[] args) {
    // i1是Integer包装类型
    Integer i1 = 10;
    // i2是基本数据类型
    int i2 = 20;
    // 进行赋值时,会发生自动拆箱
    i1 = i2;
    System.out.println(i1);
}

②比较:在包装类型与基本数据类型进行比较时,会先将包装类进行拆箱成基本数据类型(Integer→int),然后再进行比较。

public static void main (String[] args) {
    // i1是Integer包装类型
    Integer i1 = 10;
    // i2是基本数据类型
    int i2 = 20;
    // 进行比较时,会发生自动拆箱,将Integer转换成int
    if (i1 < i2)
        System.out.println("i1 小于 i2");
}

③运算符:操作符的只能对基本数据类型进行运算,所以在包装类和基本数据类型进行运算时,会发生自动拆箱,将包装类型转换成基本数据类型进行运算。

public static void main (String[] args) {
    // i1是Integer包装类型
    Integer i1 = 10;
    // i2是基本数据类型
    int i2 = 20;
    // 进行操作符运算时时,会发生自动拆箱
    int i3 = i1 + i2;
    System.out.println(i3);
}

④方法传参:有时候我们的方法形参是包装类型,传入基本数据类型时,会发生自动装箱;形参是基本数据类型,传入包装类型时,会发生自动装箱。

// 自动拆箱
public static int getNum1 (Integer a) {
    return a;
}
// 自动装箱
public static Integer getNum2 (int b) {
    return b;
}

4、常量池

(1)基本数据常量池

Java为大部分基本类型(6种)的包装类(Byte、Short、Integer、Long、Boolean、Character)实现了常量池技术,为它们创建了[-128,127]范围内的缓存数据,具体范围见下表所示。

包装类常量池范围
Byte-128 ~ 127(所有)
Short-128 ~ 127
Integer-128 ~ 127
Long-128 ~ 127
Character‘\u0000’ ~ ‘\u007F’
Booleantrue和 false

(2)用Integer i = 创建对象

当我们用Integer i = xxx创建对象时,会发生自动装箱,调用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);
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static {
        // high value may be configured by property
        int h = 127;
    }
}

这时:
①如果数据大小在缓存数据范围内,那么会直接使用获取常量池中已经创建好的数据;
②如果不在缓存数据范围内,则会用new Integer(xxx)在堆中创建新的对象。
:Float、Double并没有实现缓存池技术,这是因为浮点型数据有小数,数据个数是不可数的,没办法提前创建。

(3)用new Integer()创建对象

当我们用new Integer()创建Integer对象时,无论数据大小是多少,都会在堆中新建一个对象。

(4)具体示例

public static void main (String[] args) {
    Integer i1 = 10;
    Integer i2 = 10;
    Integer i3 = new Integer(10);
    int i4 = 10;
    int i5 = 200;
    Integer i6 = 200;
    Integer i7 = 200;
    Integer i8 = new Integer(200);
    System.out.println(i1 == i2);   // true
    System.out.println(i1 == i3);   // false
    System.out.println(i1 == i4);   // true
    System.out.println(i2 == i3);   // false
    System.out.println(i5 == i6);   // true
    System.out.println(i5 == i7);   // true
    System.out.println(i5 == i8);   // true
    System.out.println(i6 == i7);   // false
    System.out.println(i7 == i8);   // false
}
  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值