自动装箱和自动拆箱

Java 提供了 8 种基本数据类型,每种数据类型都有其对应的包装类型,包装类是面向对象的类,是一种高级的数据类型,可以进行一些比较复杂的操作,它们是引用类型而不再基本类型了。

基本类型和包装类型的对应关系

基本类型

包装类型

byte(1字节

Byte

short(2字节)

Short

int(4字节)

Integer

long(8字节)

Long

float(4字节)

Float

double(8字节)

Double

char(2字节)

Character

boolean(1字节)

Boolean

自动装箱

自动装箱,简单来说,就把基本数据类型自动包装为引用类型,

在 JDK 1.5 之前,是不能把一个基本类型直接赋值给引用类型的,需要引用类型,就必须使用创建对象的方式,如下:

Integer integer = new Integer(10);

JDK 1.5 之后,它们之间可以自由的转换,如下所示:

int j = 20;

Integer integer1 = j;

JVM 会把基本类型 j 自动包装为引用类型 Integer,这就是自动装箱;查看下它的class文件,如下:

int j = 20;

Integer integer1 = Integer.valueOf(j);

可以看到,自动装箱,就是调用 valueOf() 方法来实现的。

自动拆箱

自动拆箱,就是把一个引用类型自动转换为基本类型,如下所示:

Integer integer = new Integer(10);

int i = integer;

反编译它的class文件如下:

Integer integer = new Integer(10);

int i = integer.intValue();

可以看到,自动拆箱就是调用 intValue() 方法来实现的。

上述完整代码如下:

public class Hello {

public static void main(String[] args) {

Integer integer = new Integer(10);

int i = integer;

int j = 20;

Integer integer1 = j;

}

}

反编译class文件如下:

public class Hello

{

public static void main(String[] args)

{

Integer integer = new Integer(10);

int i = integer.intValue();

int j = 20;

Integer integer1 = Integer.valueOf(j);

}

}

还有一点需要注意的是,当在调用 valueOf() 方法的时候,默认情况下,如果需要转换的数值在 -128~127 之间,则直接从缓存中取,而不会创建 Integer 对象,源码如下:

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

接下来看下它的静态内部类 IntegerCache,它在第一次使用的时候进行加载,上面说了,默认情况下在 -128~127 之间从缓存读取,这个最大值 127 是可以配置的,通过虚拟机参数-XX:AutoBoxCacheMax=进行配置,它的源码如下:

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) {

}

}

high = h;

cache = new Integer[(high - low) + 1];

int j = low;

for(int k = 0; k < cache.length; k++)

cache[k] = new Integer(j++);

assert IntegerCache.high >= 127;

}

private IntegerCache() {}

}

接下来验证一下:

默认情况下:

Integer i1 = Integer.valueOf(-20);

Integer i2 = Integer.valueOf(-20);

System.out.println(i1 == i2); // true

Integer i3 = Integer.valueOf(20);

Integer i4 = Integer.valueOf(20);

System.out.println(i3 == i4); // true

Integer i5 = Integer.valueOf(127);

Integer i6 = Integer.valueOf(127);

System.out.println(i5 == i6); // true

Integer i7 = Integer.valueOf(-129);

Integer i8 = Integer.valueOf(-129);

System.out.println(i7 == i8); // false

Integer i9 = Integer.valueOf(128);

Integer i10 = Integer.valueOf(128);

System.out.println(i9 == i10); // false

可以看到,在 -128~127 之外,则会创建新的对象,在之间则会从缓存中读取。

接下来修改这个上限值,通过添加虚拟机参数 -XX:AutoBoxCacheMax=把上限值设置为 200

在运行上面的用例:

Integer i1 = Integer.valueOf(128);

Integer i2 = Integer.valueOf(128);

System.out.println(i1 == i2); // true

Integer i3 = Integer.valueOf(200);

Integer i4 = Integer.valueOf(200);

System.out.println(i3 == i4); // true

Integer i5 = Integer.valueOf(201);

Integer i6 = Integer.valueOf(201);

System.out.println(i5 == i6); // false

可以看到,上限值已经改变了。

Integer、Short、Byte、Character、Long 的 valueOf 方法都是和上面一样,在 -128~127 之间之间从缓存从取。

Double,Float 则不是,因为在某个范围内的整型数值的个数是有限的,而浮点数却不是

Double l1 = Double.valueOf(100.0);

Double l2 = Double.valueOf(100.0);

System.out.println(l1 == l2); //false

Double l3 = Double.valueOf(200.0);

Double l4 = Double.valueOf(200.0);

System.out.println(l3 == l4);//false

它们的 valueOf 方法如下:

public static Double valueOf(double d) {

return new Double(d);

}

public static Float valueOf(String s) throws NumberFormatException {

return new Float(parseFloat(s));

}

Boolean 类型又是如何呢?

Boolean b1 = Boolean.valueOf(true);

Boolean b2 = Boolean.valueOf(true);

System.out.println(b1 == b2);//true

Boolean b3 = Boolean.valueOf(false);

Boolean b4 = Boolean.valueOf(false);

System.out.println(b3 == b4);//true

它的源码如下:

public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

public static Boolean valueOf(boolean b) {

return (b ? TRUE : FALSE);

}

可以看到,它们指向的是同一个静态对象。

总结

1.自动装箱:把基本类自动转换为引用类型,调用的是  valueOf() 方法实现

2.自动拆箱:把引用类型自动转换为基本类型,调用的是  intValue() 方法实现

3.valueOf() 方法:Integer、Short、Byte、Character、Long 的 valueOf() 方法,在一定数值范围内直接从缓存中获取,而不会创建对象,只有超过了界限才会创建对象。Double,Float 的 valueOf() 方法每次都会创建新的对象,因为在一定范围内浮点数的个数是无限的。Boolean 对象的 valueOf() 方法调用的都是同一个静态对象。

java 自动装箱自动拆箱_自动装箱和自动拆箱相关推荐

  1. 等宽分箱_数据分析师-数据挖掘如何分箱以及对箱子中的数据进行平滑处理

    题干: 假定用于分析的数据包含属性age.数据元组中age的值如下(按递增序):13,15,16,16,19,20,20,21,22,22, 25,25,25,30,33,33,35,35,36,40 ...

  2. 华硕x580nv拆机_看懂一篇拆机贴 拆遍天下机 华硕A45VM拆机清灰换硅脂 怒降25度!...

    本帖最后由 疾影Z7 于 2017-1-11 18:06 编辑 天下龙脉尽出昆仑,同理.拆机的思路大同小异,掌握一台笔记本的拆机技巧便可拆遍天下机.拆机的诀窍是:胆大.心细.掌握好这四字诀面对市场上9 ...

  3. python自动收取蚂蚁森林能量_通过测试工具自动收取蚂蚁森林能量

    本文仅为自动化工具appium的技术研究,请勿用于任何非正当用途 最近在家远程工作,结果作息更混乱了,早上起不来,导致我蚂蚁森林能量天天被偷,严重影响我沙漠造树"大业" ‍♂️.于 ...

  4. 魅族html查看程序退出,魅族MX2左下角屏幕失灵自动点击怎么解决_魅族2程序自动返回退出的原因...

    类型:手机主题大小:5.0M语言:中文 评分:5.0 标签: 立即下载 先说说这个问题是怎么来的.可以肯定的是魅族2左下角屏幕失灵绝对不是机子硬件问题,换屏幕什么的你就去找坑吧!很简单就能解决的问题, ...

  5. python 制作抽奖箱_用Excel函数制作抽奖箱

    话说各在公司每年的年会上,或者平时的一些分组活动上,又或者是某个内部组织的业务竞赛上--偶尔会遇到抽奖或抽签的环节,例如你的公司开展了一个实操的业务竞赛,一共80道题目,参赛人员要随机抽取题目然后做答 ...

  6. java自动装箱和拆箱_关于java自动装箱和自动拆箱

    自动装箱和拆箱是一个老生常谈的问题了,今天我们谈一下我对这两个概念的理解. 一.自动装箱 java中一共有八种基本类型的数据,对于这些基本类型的数据都有一个对应的包装器类型.比如int--Intege ...

  7. java装箱与拆箱_【转】java 自动装箱与拆箱

    这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱 ...

  8. java装箱和拆箱的意义_java的自动拆箱和装箱是每个程序员都要知道的

    自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西. 自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动 ...

  9. Java基础笔记 – 增强的for循环For each循环 自动装箱拆箱 可变参数

    1.For each循环:1.1.语法:1.2.For each循环的使用:1.3.嵌套For each循环:1.4.三种循环遍历集合的列举:1.5.增强的for循环的缺点:2.自动装箱/拆箱(Aut ...

  10. java模拟加速匀速减速_【JavaSE练习】面向对象_练习_模拟汽车的自动驾驶系统

    [JavaSE练习]面向对象_练习_模拟汽车的自动驾驶系统 [JavaSE练习]面向对象_练习_模拟汽车的自动驾驶系统 模拟汽车驾驶系统 定义一个交通工具的类,包括: 属性:速度 方法:设置速度,加速 ...

最新文章

  1. Ext.app.controller的refs
  2. CentOS/RHEL6.5中使用WordPress快速建站
  3. vs2015打开EXCEL文档范例及其注意事项!!!
  4. 服务器部署ssl证书,Apache服务器SSL证书部署
  5. ubuntu16.04 安装中文输入法
  6. 信号与线性系统分析(吴大正,郭宝龙)(信号的分类)
  7. Maven下载JasperReports报错Could not find artifact com.lowagie:itext:pom:2.1.7.js6 in alimaven
  8. Mysql密码忘记怎么办?重置密码完整教程
  9. Android中插件化实现的原理,宿主app运行插件中的类 (一)
  10. oracle报1405,【案例】Oracle报错ORA-15054 asm diskgroup无法mount的解决办法
  11. 闭关之 Vulkan 应用开发指南笔记(二):队列、命令、移动数据和展示
  12. 超详细的数据分析职业规划
  13. 上海滩第一代炒股大户沉浮录
  14. 大数据即席查询工具——秒级响应
  15. 机器学习工程师 - Udacity 项目:实现一个狗品种识别算法App
  16. 关于cv2.cvtColor(im, cv2.COLOR_RGB2BGR)的一点细节
  17. Vert.x(vertx) Web开发-路由
  18. 2019-2020记罗振宇“时间的朋友”跨年演讲(一)
  19. 荐书丨《进化心理学》:刘耕宏、王心凌背后的魔力之谜
  20. 查看电脑IP端口配置/Windows Ipconfig命令教程

热门文章

  1. SQL--(MyBatis 实战)
  2. 英国继银行被窃之后 信贷公司Wonga数十万客户数据被泄
  3. hive数据仓库摘录和总结
  4. QThread中的互斥、读写锁、信号量、条件变量
  5. 2017电大c语言形考册,(2017年电大)中央广播电视大学c语言程序设计形成性考核册及答案.doc...
  6. 文字加减前后缀lisp_华为笔试题---仿LISP算法
  7. js调用python脚本_javascript – 如何从NodeJs调用python脚本
  8. cdr放大后内容消失了_放大镜+定时器+画笔,582KB软件就能做到,上网课的你一定能用上...
  9. android api版本 闪退_经验分享:从事 Android 开发六年,我学到的那些事
  10. 2013年上半年全国高等学校(安徽考区)计算机水平考试试卷,2013年上半年全国高等学校(安徽考区)计算机水平考试试卷(6页)-原创力文档...