Java基础,对象包装类与自动装箱

在Java编程中,基本数据类型(如intcharboolean等)虽然高效,但在某些情况下需要将其作为对象使用,例如在集合类中存储数据时。为此,Java提供了对应的包装类,并通过自动装箱自动拆箱机制简化了基本类型与对象之间的转换。然而,这也带来了一个常见的“128陷阱”,本文将详细介绍这些概念。

一、包装类


public class Demo{
    public static void main(String[] args){
        int a = 10;
        float b = 10.0f;
        Cat cat = new Cat();
        a = b;
        a = cat;            
    }
}

在这个地方我们可以看到我们定义了几个变量,变量的基本赋值并没有什么问题,但是后边我们让a=b;a=cat;

却不能这样赋值,因为我们不可以让一个float类型的数据装载到int类型当中。

包装类是基本数据类型的对象表示形式,每个基本数据类型都有对应的包装类,如下表所示:

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

这些包装类允许基本类型在需要对象的上下文中使用,例如在集合框架中。包装类还提供了许多有用的方法,比如将字符串转换为基本类型,反之亦然。

二、自动装箱与自动拆箱

自动装箱是指Java编译器自动将基本数据类型转换为对应的包装类对象的过程。自动拆箱则是将包装类对象自动转换回基本数据类型的过程。这种机制极大地简化了代码编写,减少了手动转换的麻烦。

1、自动装箱与拆箱的示例

public class AutoboxingUnboxingExample {
    public static void main(String[] args) {
        // 自动装箱:将int转换为Integer对象
        Integer integerObject = 100;

        // 自动拆箱:将Integer对象转换为int
        int intValue = integerObject;

        // 包装类对象之间的运算,会先进行自动拆箱,然后再进行运算
        Integer anotherInteger = 200;
        int result = integerObject + anotherInteger; // 自动拆箱后相加
        System.out.println("Result: " + result);
    }
}

三、128陷阱

Java中的“128陷阱”与自动装箱和拆箱密切相关,特别是在处理Integer包装类时。

1、产生原因

Integer类在装箱过程中,对于值在-128127之间的整数,Java会使用内部缓存池来复用这些对象。这意味着相同的数字在这个范围内会共享同一个Integer对象。而对于超过这个范围的整数,Java则会创建新的Integer对象。

代码:

public class IntegerCachingExample {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;

        Integer c = 128;
        Integer d = 128;

        System.out.println(a == b); // true
        System.out.println(c == d); // false
    }
}

ab指向同一个Integer对象,因为它们的值在-128127之间,Java从缓存中复用了相同的对象。因此,a == b返回true

cd由于超出了-128127的范围,Java为每个对象创建了新的Integer对象。因此,c == d返回false

2、如何避免128陷阱

在比较包装类对象时,应该使用equals()方法而不是==操作符。equals()方法会比较对象的值,而==操作符比较的是对象的内存地址。

public class IntegerComparisonExample {
    public static void main(String[] args) {
        Integer c = 128;
        Integer d = 128;

        System.out.println(c.equals(d)); // true
    }
}

在这个示例中,c.equals(d)正确地返回true,因为它比较的是对象内部的值,而不是对象引用。

四、示例


public static void main(String[] args){
    int a = 10;
    int b = 10;
    Integer a1 = 10;
    Integer b1 = 10;
    Integer a2 = new Integer(10);
    Integer b2 = new Integer(10);
 
    System.out.println(a1 == b1);  // true
    System.out.println(a2 == b2);  // false
    System.out.println(a1 == a);   // true
    System.out.println(a1.equals(a)); // true
    System.out.println(a1 == a2);  // false
    System.out.println(a == a2);   // true
}

解释:

 1.System.out.println(a == b); // true

                解释:a 和 b 都是基本类型 int,它们的值相同,所以比较结果为 true。

 2.System.out.println(a1 == b1); // true

                解释:a1 和 b1 都是通过直接赋值 10 创建的 Integer 对象。由于 Java 对于值在 -128 到 127 之间的整数进行缓存,a1 和 b1 实际上指向同一个对象,所以结果为 true。

 3.System.out.println(a2 == b2); // false

                解释:a2 和 b2 是通过 new Integer(10) 创建的,它们是两个不同的对象,虽然值相同,但内存地址不同,因此结果为 false。

 4.System.out.println(a1 == a); // true

                解释:这里发生了自动拆箱(unboxing),a1 被转换成基本类型 int,然后与 a 进行比较。由于它们的值相同,所以结果为 true。

 5.System.out.println(a1.equals(a)); // true

                解释:equals() 方法比较的是值。a1 是 Integer 对象,a 是 int 基本类型,a1 自动拆箱为 int,然后与 a 进行比较,值相同,因此结果为 true。

 6.System.out.println(a1 == a2); // false

                解释:a1 是通过自动装箱(autoboxing)创建的,而 a2 是通过 new Integer(10) 创建的对象,两个对象的引用不同,结果为 false。

 7.System.out.println(a == a2); // true

                解释:a2 是 Integer 对象,通过自动拆箱,a2 被转换成基本类型 int,然后与 a 进行比较,值相同,因此结果为 true。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值