Java包装类

目录

什么是包装类

包装类的定义

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

Integer类型的特点

为什么Integer类型的a1 == a2为true,其中a1和a2的值为10,而a3 == a4为false,a3和a4的值为1000

128陷阱详细分析

自动拆装箱

自动装箱

自动拆箱

练习示例

总结


什么是包装类

包装类的定义

包装类(Wrapper Class)是Java编程语言中的一个重要概念,用于将基本数据类型封装为对象类型。Java是一种面向对象的编程语言,但其基本数据类型(如int、byte、float等)并不支持面向对象的特性,如继承、多态等。为了弥补这一不足,Java为每种基本数据类型都提供了一个对应的包装类,这些包装类位于java.lang包中。包装类的主要作用是允许基本数据类型像对象一样使用。

具体来说,Java中的八种基本数据类型及其对应的包装类如下:

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

包装类与基本数据类型的区别主要在于包装类本质上是一个类,因此它是一个引用数据类型,而基本数据类型是存储在栈中的原始值类型。

基本数据类型

直接存储数值,存储在栈中,效率高,但是不具备对象的特性。例如,int类型的变量a = 10,只是在内存中存储了数值10。

包装类

存储在堆中,可以为基本数据类型提供更多的方法和属性,具有面向对象的特性。例如,Integer类型的变量a1 = 10是一个对象,除了存储数值10,还可以调用equals()等方法。

举例来说,int类型的10与Integer类型的10有以下不同:

int只是一个数据类型,只能表示10在内存中如何存储。

Integer是一个类,不仅能够表示数值10,还包含许多方法,例如可以调用equals()方法,而int只能通过==进行值的比较。

Integer类型的特点

为什么Integer类型的a1 == a2为true,其中a1和a2的值为10,而a3 == a4为false,a3和a4的值为1000

让我们来看一个示例代码:

public class Test {

    public static void main(String[] args) {

       Integer a1 = 10;

       Integer a2 = 10;

       System.out.println(a1 == a2); // 输出 true

      

       Integer a3 = 1000;

       Integer a4 = 1000;

       System.out.println(a3 == a4); // 输出 false

    }

}

输出结果:

true

false

原因

包装类是引用数据类型,在引用数据类型中,

==比较的是对象的内存地址是否相同。

对于

a1 == a2返回true,而a3 == a4返回false的原因,实际上是因为Integer的valueOf()方法。Java对于数值在-128到127之间的Integer对象会在一个缓存数组中存储,这个数组相当于一个缓存池。

当你创建一个数值在-128到127之间的Integer对象时,它会直接返回该值在数组中的地址。所以在这个范围内的数值用==比较是相等的。

而超出这个范围的数值,则会新开辟一个内存空间,因此它们的地址不同,所以比较结果为false。

128陷阱详细分析

Integer类型的一个重要方法是Integer.valueOf()。在文件中定义一个Integer类型变量,通过javac编译和javap -c反编译该文件可以发现,像Integer b = 10;这样的代码会被编译成Integer b = Integer.valueOf(10);,涉及到自动装箱。

工作原理

Integer.valueOf()

方法在数值在-128到127之间时,会返回缓存中的相同地址的对象。如果数值不在这个范围内,则会调用new Integer()方法,开辟新的内存空间。

valueOf()方法的取值范围是通过查看代码中low和high值定义的,它们分别为-128和127。当数值在这个范围内时,valueOf()方法返回的是缓存池中对应的数值对象,这就解释了为什么a1和a2相等,而a3和a4不等。

自动拆装箱

在讨论128陷阱时,我们提到过自动拆装箱。自动拆装箱是Java中的一种特性,主要涉及基本数据类型与它们对应的封装类之间的自动转换。

自动装箱

自动装箱是指将基本数据类型自动转换为封装类对象的过程。Java自动将基本类型的值赋给相应的包装类对象,例如:

Integer b = 10; // 自动装箱

编译后,这段代码实际上等价于:

Integer b = Integer.valueOf(10);
自动拆箱

自动拆箱是指将封装类对象自动转换为基本数据类型的过程。例如:

Integer b = 10;

int a = b; // 自动拆箱

编译后,这段代码等价于:

int a = b.intValue();

练习示例

以下是一个练习示例,帮助更好地理解包装类和基本数据类型的差异,以及自动拆装箱的机制:

public class Test {

    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(a == b);   // 输出:true

       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

    }

}

解释

System.out.println(a == b);

输出:true

原因:a和b是基本数据类型,==比较的是它们的值,两个int值相等,所以结果是true。

System.out.println(a1 == b1);

输出:true

原因:a1和b1是Integer类型,值在-128到127之间,所以从缓存中取得相同的对象引用,==比较的是内存地址,相同,所以结果是true。

System.out.println(a2 == b2);

输出:false

原因:a2和b2使用new关键字创建,每次都会创建新的对象,所以它们的内存地址不同,==比较结果为false。

System.out.println(a1 == a);

输出:true

原因:a1是包装类,a是基本类型,在使用==比较时,a1会自动拆箱为int类型,然后与a进行值比较,结果是true。

System.out.println(a1.equals(a));

输出:true

原因:equals()方法会判断a是否为Integer类型,然后拆箱比较值是否相同,结果是true。

System.out.println(a1 == a2);

输出:false

原因:a1是缓存中的对象,a2是新创建的对象,内存地址不同,==比较结果为false。

System.out.println(a == a2);

输出:true

原因:a2是包装类对象,a是基本数据类型,a2会自动拆箱为int类型,与a进行值比较,结果是true。

总结

包装类在Java中是一个重要的特性,允许基本数据类型拥有对象的特性,从而支持更多的操作和方法调用。理解包装类的工作原理,特别是自动拆装箱和Integer缓存机制,有助于我们更好地编写和优化Java代码。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值