在刚刚学习java的时候,老师不止一次的说过java是一种面向对象的语言,万物皆对象。对于java中的基础数据类型,由于为了符合java中面向对象的特点,同样也有其封装类。这篇文章对其有一个认识。
一、基本认识
其实在jdk1.5之前,在基础数据类型与其封装器之间的转化必须手动进行,但是从jdk1.5之后,由于提供了自动装箱的机制,因此我们不再手动进行了。
装箱:基础类型转封装类型。Integer a = 3底层实现:Integer a = Integer.valueOf(3);拆箱:封装类型转基础类型。int b = a;底层实现:int b = a.intValue();
既然封装类能够封装基础类型,那么能封装的范围是多少呢?
![b393189f677b36a3fa3ffc9cb94c4e0d.png](https://i-blog.csdnimg.cn/blog_migrate/d1bcf7c0b58a210f95be9a6d175b9dbe.jpeg)
我们对其进行了一个总结。不过我们应该注意到boolean类型没有给出精确的定义,可能是一个字节也有可能是四个字节,这是为什么呢?java虚拟机规范中规定的是4个字节,但是不同的厂家虚拟机可能不同,所以可能不会按照规范来。
以上这张图想必我们都不陌生,每一种基础类型都有一个唯一的封装类。而且也给出了字节数、最大值最小值等。下面我们就看一下其基本使用:
![5df582482944745ccc1e19b6d9af0934.png](https://i-blog.csdnimg.cn/blog_migrate/811da28f26d5e3ea1993813fcc27694c.jpeg)
二、基础类型与封装类的区别
1、传递方式不同
基本类型是按值传递,而封装类型是按引用传递的。int是基本类型,直接存放数值;Integer类会产生一个对象引用指向这个对象。
2、存储位置不同
基本类型存储在栈中,封装类的引用存储在栈中,而值是存在堆中。这样看上去好像基础封装类多此一举,而且基本类型的速度也确实会比封装类更快。为什么快呢?这是因为封装类涉及到了对象内存的分配和垃圾回收。但是基本类型直接拿起来就计算了。
三、源码分析
在讲解源码之前我们先给出一个神奇的例子,请看下面的代码:
![98a7cc7c2f24fec08074b1e3cf07d6a9.png](https://i-blog.csdnimg.cn/blog_migrate/611a3077ee1ba889d183e40fc3e8f9ac.jpeg)
第一种情况感觉和第二种情况一模一样呀,为什么第二种是false呢?想要知道原因,我们就必须要深入到源码中找寻答案。
![66e7a1ed4fd905bbaabf638ffc333ae8.png](https://i-blog.csdnimg.cn/blog_migrate/a758c2d67cf2a8a548bd4ad5bc2878b3.jpeg)
也就是说,在合理表示范围之内就直接拿出来一个旧的数据,如果不在表示范围之内那就创建一个新的。但是对于源码的了解不能仅限于此。我们还是按部就班的分析,下面我们以Integer封装类为例。
1、参数
![225440f3c6171d2699cd4bf7b732a035.png](https://i-blog.csdnimg.cn/blog_migrate/bcf7e1ac3bb05f73ffa4f3c224e75c18.jpeg)
2、方法
![2600533d05b950cc48802e3e00e2a499.png](https://i-blog.csdnimg.cn/blog_migrate/db4808bb588fd634f098c27a6d43956e.jpeg)
3、缓存
上面支持给出了一些基本的使用方法,不过最核心的还是缓存范围的实现。下面我们看一下:
![baa6589cb743de57684eedd158a473ac.png](https://i-blog.csdnimg.cn/blog_migrate/caa10d53687d5f99e5428efeeae478f7.jpeg)
上面这些代码能看懂最好,看不懂我来描述一下大概意思:这是一个静态内部类,类中定义一个静态cache数组,这个静态数组预先放了自己指定范围内的数据,拆箱的时候首先判断范围然后从缓存数组中去抓取数据。就是这么一个简单的过程。
四、使用场景
上面分析了这么多,最主要的还是如何使用,在什么地方使用。下面我们就总结几个场景:
1、类型之间的转换:
![6bb8e35f2468b40ebf717b4a3f0f9f92.png](https://i-blog.csdnimg.cn/blog_migrate/a1f788e47b6baa57c603c9dc34cfcdd3.jpeg)
2、泛型中使用
List<>为原始类型,不指定元素类型时,会出现不安全的警告:
List is a raw type. References to generic type Listshould be parameterized
大概意思就是:List的<>中应该指定清楚是那种类型,如Integer、String等。
3、强制类型转换
4、集合中使用
![da30f9cbb892f2dbae6007ba25d88814.png](https://i-blog.csdnimg.cn/blog_migrate/27dad1c26cdc1def592760be233f71d8.jpeg)
这种情况下会出现空指针异常。
OK。今天的文章先到这里,如有问题还请批评指正。