主要是阅读一些基本Java编程规范的读书笔记,第一次写博客,还需要多多努力
Java的装箱与拆箱
基本数据类型
Java中的基本数据类型共有八种,分为数值型,字符型, 布尔型
字符类型: char
布尔类型: boolean
数据类型: int, float, double, byte, short, long
与C#有所不同
Java是一种全面向对象的语言,和C#一样都是对象全在堆里面,然后C#就是数值类型和引用类型,Java就搞出来了基本类型和对象类型
Java和C++的基本数值类型也不一样,Java的数值都没有无符号这一说,这也是要全平台运行的设计需求决定的,程序设计者也不想考虑在某个平台上的运行错误。因为数值类型不存储在栈里就会变慢,但是这样就会导致溢出,所以为了想两全其美 ,只有把基本数据类型封装成一种类,这样就给程序设计人员一种方式来处理更复杂情况下的数据。
如果计算发生了溢出如图所示:
1 | int i = Integer.MAX_VALUE; |
输出结果: 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 | Integer i =10; //自动装箱 |
c#中的装箱如下,需要注意的是,本质上只是创建了一个object的副本。
1 | int i = 10; |
自动装箱下的实际操作
1 | List<Integer> li = new ArrayList<>(); |
如果在大型计算中,注意不要进行integer的复杂计算,否则会带来自动拆箱的效率问题:
1 | Integer i = Integer.valueOf(10); |
以及flage?(integer)i:(int)j;
如果i是null会导致空指针异常nullPointerError
自动装箱带来的问题
当然,自动拆装箱是一个很好的功能,大大节省了开发人员的精力,不再需要关心到底什么时候需要拆装箱。但是,他也会引入一些问题。
包装对象的数值比较,不能简单的使用
==
,虽然-128到127之间的数字可以,但是这个范围之外还是需要使用equals
比较。前面提到,有些场景会进行自动拆装箱,同时也说过,由于自动拆箱,如果包装类对象为null,那么自动拆箱时就有可能抛出NPE。
如果一个for循环中有大量拆装箱操作,会浪费很多资源。
参考资料 一文读懂什么是Java中的自动拆装箱