深入理解Java中的装箱与拆箱
一、Java数据类型
1、在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是:
- 整数型:byte̵,short̵,int̵,long
- 浮点型:float,double
- 字符型:char
- 布尔型:boolean
| 数据类型 | 内存 | 默认值 | 包装类 |
|---|---|---|---|
| byte | 8位 | 0 | Byte |
| short | 16位 | 0 | short |
| int | 32位 | 0 | Integer |
| long | 64位 | 0L或0l | Long |
| float | 32位 | 0.0F或0.0f | Float |
| double | 64位 | 0.0D或0.0d | Double |
| char | 16位 | \u0000 | Character |
| boolean | 8位 | flase | Boolean |
2、引用类型:
- 数组
- 类(class)
- 接口(Interface)
- 枚举(enum)

3、值类型与引用类型的区别
- 从概念方面上来说:
- 值类型:变量名指向具体的值
- 引用类型:变量名指向数据对象的内存地址
- 从内存构建方面上来说:
- 值类型:变量在声明之后,Java就会立刻分配给它内存空间
- 引用类型:它以特殊的方式(类似C指针)指向对象实体,这类变量声明时不会分配内存,只是存储
- 从使用方面上来说:
- 值类型:使用时需要赋具体值,判断时用 ” == “号
- 引用类型:使用时可以赋null,判断时使用 equals 方法
二、Java数据类型转换
1、自动转换
定义:程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换
优先关系:按从低到高的顺序转换。不同类型数据间的优先
关系如下:
- 低--------------------------------------------->高
- byte,short,char-> int -> long -> float -> double
转换规则:
运算中,不同类型的数据先转化为同一类型,然后进行运算
操作数1类型 操作数2类型 转换后的类型 byte、short、char int int byte、short、char、int long long byte、short、char、int、long float float byte、short、char、int、long、float double double
2、强制转换
定义:强制类型转换则必须在代码中声明,转换顺序不受限制
格式:在需要转型的数据前加上“( )”,然后在括号内加入需要转化的数据类型
结果:精度可能会丢失,也可能更加精确
int x;
double y; x = (int)3.14 + (int)5.20 //精度丢失
y = (double)x + (double)8 //精度提升 输出:x = 8;y = 16.0
三、Java之装箱与拆箱
1、包装类
- Java是面向对象语言,号称万事万物皆对象,因此,8种基本数据类型有了对应的类,这就是包装类
2、什么是装箱与拆箱
装箱:将值类型装换成引用类型的过程
拆箱:将引用类型转换成值类型的过程
自动装箱:
int x = 3;
Integer y = x; //int --> Integer,Integer y = x <==> Integer y = Integer.valueOf(x)
自动拆箱:
Integer x = new Integer(5);
int y = x; //Integer --> int,int y = x <==> int y = x.intValue()
3、装箱和拆箱是如何实现的
- 装箱过程是通过调用包装器的valueOf方法实现的
- 拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)
4、注意点:
大量使用自动拆装箱会使性能降低,还会造成大量的内存消耗
在重载方法中,可能出现问题
List<Integer> list = new ArrayList<>();
Integer x,y,z;
x = 1;y = 2;z = 4;
list.add(x);list.add(y);list.add(z); list.remove(2);

在上面这段代码中ArrayList.remove方法有两个重载方法,那么list.remove(2)是调用了哪个方法,remove掉的是值为2的对象,还是remove了index为2,值为4的那个对象呢?
在这种情况下,编译器不会进行自动拆装箱,所以调用的是remove(int index),index为2值为4的这个Integer对象会被remove.
如果要调用 remove(Object o)的方法,应该这么写 list.remove(y)
缓存值问题
案例解析:
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4); Output: true false
观察源码:
Intteger.valueOf方法
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache类
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}
从源码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象
Byte、Short、Integer、Long四种包装类默认创建了数值为[-128,127]的相应类型的缓存数据,但是超出此范围仍会创建新的对象。
Character默认会创建[0,127]的响应类型的缓存数据
两种浮点型没有实现常量池技术,在某个范围内的整型数值的个数是有限的,而浮点数却不是
包装类 常量池 常量池范围 Byte 存在 [-128,127] Short 存在 [-128,127] Integer 存在 [-128,127] Long 存在 [-128,127] Character 存在 [0,127] Float 不存在 无 Double 不存在 无 注意点:
- 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
- 对于包装器类型,equals方法并不会进行类型转换
- 算术运算会触发装箱与拆箱过程
注意点:
- 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
- 对于包装器类型,equals方法并不会进行类型转换
- 算术运算会触发装箱与拆箱过程
参考文章:https://www.cnblogs.com/dolphin0520/p/3780005.html
深入理解Java中的装箱与拆箱的更多相关文章
- 第六节:详细讲解Java中的装箱与拆箱及其字符串
前言 大家好,给大家带来详细讲解Java中的装箱与拆箱及其字符串的概述,希望你们喜欢 装箱与拆箱 封装类有:Byte , short , Integer , Character , long , Fl ...
- 深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
- 从别人那淘的知识 深入剖析Java中的装箱和拆箱
(转载的海子的博文 海子:http://www.cnblogs.com/dolphin0520/) 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来 ...
- [ 转载 ]学习笔记-深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
- 【转】深入剖析Java中的装箱和拆箱
深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...
- (转)深入剖析Java中的装箱和拆箱
转:https://www.cnblogs.com/dolphin0520/p/3780005.html 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就 ...
- java语法糖3 深入剖析Java中的装箱和拆箱
装箱 在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行: Integer i = new Integer(10); 而在从Java SE5开始就提供了自动装箱的特性, ...
- 深入剖析Java中的装箱和拆箱(转)
自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱.拆箱相关的问题. 以下是本文的 ...
- 深入剖析Java中的装箱和拆箱(缓存池技术)
以下是本文的目录大纲: 一.什么是装箱?什么是拆箱? 简单一点说,装箱就是 自动将基本数据类型转换为包装器类型:拆箱就是 自动将包装器类型转换为基本数据类型. 二.装箱和拆箱是如何实现的 1:反编 ...
随机推荐
- C# ASP 上传/下载文件
1. 上传文件前台页面 <div style="padding-left:20px;"> <asp:FileUpload ID="FileUpload ...
- mapper.xml文件中传入list参数报错 ‘ ’附近有语法错误
mapper.xml文件中传入list参数,使用foreach循环遍历值,但是在遍历的过程中出错了,具体代码如下所示 mapper.xml <select id="selectByCo ...
- 2020-07-20:你觉得redis有什么缺点,给你改进的话你会怎么改进?
福哥答案2020-07-20: 1.由于 Redis 是内存数据库,短时间内大量增加数据,可能导致内存不够用.2.redis是单线程的,单台服务器无法充分利用多核服务器的CPU.3.遇到大量查询时容易 ...
- Java爬取先知论坛文章
Java爬取先知论坛文章 0x00 前言 上篇文章写了部分爬虫代码,这里给出一个完整的爬取先知论坛文章代码. 0x01 代码实现 pom.xml加入依赖: <dependencies> & ...
- Linux内核之 进程管理
正如上一篇我们提到过,进程是Linux系统中仅次于文件的基本抽象概念.正在运行的进程不仅仅是二进制代码,而是数据.资源.状态和虚拟的计算机组成.我们今天主要介绍进程的概念,组成,运行状态和生命周期等. ...
- 轻量级Java EE企业应用实战:Struts2+Spring5+Hibernate5/JPA2
轻量级Java EE企业应用实战(第5版)——Struts 2+Spring 5+Hibernate 5/JPA 2整合开发是<轻量级Java EE企业应用实战>的第5版,这一版保持了前几 ...
- Android CC框架中,新建组件无法显示布局问题
出错: 当在创建新的组件时,跳转到新组件成功,但是无法正确显示布局,即获取到布局文件的控件等. 原因: 当在创建新的组件时,默认生成MainActivity以及其布局activity_main.每个组 ...
- Url跳转漏洞常见
Url跳转漏洞常见出现点: 1.用户登录.统一身份认证处,认证完后会跳转. 2.用户分享.收藏内容过后,会跳转. 3.跨站点认证.授权后,会跳转. 4.站内点击其它网址链接时,会跳转. Url跳转漏洞 ...
- mysql-STRAIGHT_JOIN-优化
性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间. 首先来解释下STRAIGHT_JOIN到底是用做什么的: STRAIGHT_JOIN is simi ...
- JavaScript学习系列博客_17_JavaScript中的函数的参数、返回值
数的形参(形式参数) - 定义函数时,可以在()中定义一个或多个形参,形参之间使用英文逗号隔开:定义形参就相当于在函数内声明了对应的变量但是并不赋值,形参会在调用时才赋值. 函数的实参(实际参数) - ...