Java的装箱与拆箱

主要是阅读一些基本Java编程规范的读书笔记,第一次写博客,还需要多多努力

Java的装箱与拆箱

基本数据类型

Java中的基本数据类型共有八种,分为数值型,字符型, 布尔型

  1. 字符类型: char

  2. 布尔类型: boolean

  3. 数据类型: int, float, double, byte, short, long

与C#有所不同
Java是一种全面向对象的语言,和C#一样都是对象全在堆里面,然后C#就是数值类型和引用类型,Java就搞出来了基本类型和对象类型
Java和C++的基本数值类型也不一样,Java的数值都没有无符号这一说,这也是要全平台运行的设计需求决定的,程序设计者也不想考虑在某个平台上的运行错误。因为数值类型不存储在栈里就会变慢,但是这样就会导致溢出,所以为了想两全其美 ,只有把基本数据类型封装成一种类,这样就给程序设计人员一种方式来处理更复杂情况下的数据。

如果计算发生了溢出如图所示:

1
2
3
4
5
int i = Integer.MAX_VALUE;
int j = Integer.MAX_VALUE;

int k = i + j;
System.out.println("i (" + i + ") + j (" + j + ") = k (" + k + ")");

输出结果: i (2147483647) + j (2147483647) = k (-2)

包装类型

为了解决基本数据类型会产生溢出的现象,将基本类型封装成为一个类

基本数据类型 包装后的类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
double Double
float Float

注意:变量名小写,类名大写

毫无疑问,全面向对象的语言有一个特点,就是什么都是对象,显然这是一种理想的状态,丰富的数据类型,才可以面对丰富的情况,类:丰富的属性和方法,全都继承于object,更多的扩展性带来了效率的低下,相比基本类型更快,好用,但是扩展性低。

将存在栈内的的数据变成存在堆中的对象,Java SE5 以上的版本增加了自动装箱技术;在C#中也可以进行相似的转换:

1
2
Integer i =10;  //自动装箱
int b= i; //自动拆箱

c#中的装箱如下,需要注意的是,本质上只是创建了一个object的副本。

1
2
3
int i = 10;
object oi = i;
int j = (int) oi;

自动装箱下的实际操作

1
2
3
4
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i ++){
li.add(i); //实际的操作: li.add(Integer.valueOf(i));
}

如果在大型计算中,注意不要进行integer的复杂计算,否则会带来自动拆箱的效率问题:

1
2
3
Integer i = Integer.valueOf(10);
Integer j = Integer.valueOf(20);
System.out.println(i.intValue() + j.intValue());

以及flage?(integer)i:(int)j; 如果i是null会导致空指针异常nullPointerError

自动装箱带来的问题

当然,自动拆装箱是一个很好的功能,大大节省了开发人员的精力,不再需要关心到底什么时候需要拆装箱。但是,他也会引入一些问题。

包装对象的数值比较,不能简单的使用==,虽然-128到127之间的数字可以,但是这个范围之外还是需要使用equals比较。

前面提到,有些场景会进行自动拆装箱,同时也说过,由于自动拆箱,如果包装类对象为null,那么自动拆箱时就有可能抛出NPE。

如果一个for循环中有大量拆装箱操作,会浪费很多资源。

参考资料 一文读懂什么是Java中的自动拆装箱

-------------本文结束感谢您的阅读 :D -------------
Show comments from Gitment