Java中的AutoBoxing与AutoUnboxing

原创作品,转载请注明出自xelz's blog

博客地址:http://mingcn.cnblogs.com/

本文地址:http://mingcn.cnblogs.com/archive/2010/10/20/JavaAutoBoxing.html

 

Java中基本数据类型(值类型)只有8种:

boolean,byte,char,short,int,long,float,double

在声明的时候,JVM会在(Stack)中分配一定的空间,里面用于存放数据对象的值

引用数据类型,如

(class)、接口(interface)、数组(Array)

它们在声明的时候,JVM会首先在(Heap)中分配该类型大小的空间,用于存放成员变量,然后在栈中分配一小块内存,用于存放指向堆中那块内存的引用(Reference)

 

很多时候我们在传参数的时候需要一个Object类型的对象或其子类的对象,而基本数据类型并不是任何类的实例,因此Java引入了BoxingUnboxing

Boxing:将基本数据类型封装成引用类型,首先在堆中分配一块内存,将基本数据对象的值拷贝进去,然后在栈中创建引用,Boxing之后的两个对象是不相干的

 

1
Integer i = new Integer(1);
Integer类中有一个属性,用于存放封装的值
1
private final int value;
可见它封装的值是final(终态)的,也就是不可变的,对其赋新值其实是创建的一个新的对象

 

Unboxing:将包装类型转换成基本数据类型,Boxing的逆操作

1
int ii = i.intValue();

 

从Java5.0之后,JVM可以直接进行AutoBoxingAutoUnboxing,下面的代码是合法的

1
2
Integer i = 1;
int ii = i;

 

下面看个例子:

1
2
3
4
5
6
7
8
Integer a = 100;
Integer b = 100;
Integer c = 1000;
Integer d = 1000;
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(c == d);
System.out.println(c.equals(d));

既然是引用类型,我们期望得到false,true,false,true的结果,但是事实并非如此,运行结果如下

true

true

false

true

这是为什么呢?参考一下这里http://java.sun.com/docs/books/jls/third_edition/html/conversions.html

If the value p being boxed is truefalse, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then letr1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

如果将要被封装的变量p是true,false,byte型,\u0000 - \u007f的char型,或者值在-128到127之间的int或short型,那么如果r1和r2是两个p的封装实例,r1 == r2总是成立

也就是说 如果数值在-128 ~ 127之间,同一个值的所有封装共用同一个对象,这发生在AutoBoxing过程中

如果要避免这种情况,请使用这种方法:

1
2
3
Integer a = new Integer(100);
Integer b = new Integer(100);
System.out.println(a == b);//false

 

最后我们总结下"=="

对于值相等的两个“对象”,如果有一个是基本数据类型,则"=="总恒为true(这里其实是将包装类型UnBoxing)

如果两个都是包装类型,则

如果有一个是通过new创建出来的,"=="为false(分配了新的空间)

否则(即都不是通过new创建,AutoBoxing的结果)

如果该值是boolean/byte/float/double类型之一

或者char/short/int/long类型之一并且值范围在-127 ~ 128之间,==为true,否则==为false

(关于float、double、long型,上文并未提到,读者可自行验证,在此不作赘述)

posted @   xelz  阅读(1878)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示