以前都没有听说过,这次看海子的博客,真是长见识了!

https://www.cnblogs.com/dolphin0520/p/3780005.html

简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

1 //自动装箱

2 Integer num = 3;3 //自动拆箱

4 int count = num;

在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。

因此可以用一句话总结装箱和拆箱的实现过程:

装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。

下面这段代码是Integer的valueOf方法的具体实现:

public static Integer valueOf(int i) {

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

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

return new Integer(i);

}

在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

IntegerCache.cache[]是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象。

上面我们看到在Integer的构造函数中,它分两种情况:

1、i >= 128 || i < -128 =====> new Integer(i)

2、i < 128 && i >= -128 =====> SMALL_VALUES[i + 128]

1 static final Integer cache[]= new Integer[256];

cache本来已经被创建好,也就是说在i >= 128 || i < -128是会创建不同的对象,在i < 128 && i >= -128会根据i的值返回已经创建好的指定的对象。

下面是几个例子:

1 packagelesson1213;2

3 public classTestZhuangXiang {4

5 public static voidmain(String[] args) {6 //自动装箱

7 Integer num1 = 3;8 Integer num2 = 3;9

10 Integer num3 = 200;11 Integer num4 = 200;12

13 System.out.println(num1==num2); //true

14 System.out.println(num3==num4); //false

15

16 }17

18 }

如果是Double类呢?

1 Double d1 = 1.0;2 Double d2 = 1.0;3 Double d3 = 200.0;4 Double d4 = 200.0;5

6 System.out.println(d1==d2); //false

7 System.out.println(d3==d4); //false

看看上面的执行结果,跟Integer不一样,这样也不必奇怪,因为它们的valueOf实现不一样,结果肯定不一样,那为什么它们不统一一下呢?

这个很好理解,因为对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,我们事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了。

但是对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的。

总结一句就是:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样。

1 public static Double valueOf(doubled) {2 return newDouble(d);3 }

下面我们进行一个归类:

Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。

下面对Integer派别进行一个总结,如下图:

下面我们来看看另外一种情况:Boolean类

1 Boolean b1 = true;2 Boolean b2 = true;3 Boolean b3 = false;4 Boolean b4 = false;5 System.out.println(b1==b2); //true

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

可以看到返回的都是true,也就是它们执行valueOf返回的都是相同的对象。

1 public static Boolean valueOf(booleanb) {2 return (b ?TRUE : FALSE);3 }

可以看到并没有创建对象,因为已经在内部提前创建好了两个对象,因为只有两种情况,这样也是为了避免重复创建太多对象。

1 public static final Boolean TRUE = new Boolean(true);2 public static final Boolean FALSE = new Boolean(false);

下面讲述下equal  和 == 在这几个类中的应用

1 packagelesson1213;2

3 public classTest {4

5 /*1:== 比较两个值是否相等。如果作用于基本数据类型,比较其值是否相等。6 * 如果作用于引用类型变量,则比较的是所指向对象的地址。7 2:在object中equal,equal方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。8 但是有一些类例如String,Double, Date,Interger等,都对equal方法进行了重写用来比较应用的对象所存储的值是否相等。9 注意equal不能用于基本数据类型。10 */

11

12 public static voidmain(String[] args) {13 Integer num1 = 200;14 int num2 = 200;15 System.out.println(num1==num2); //true

16 System.out.println(num2==num1); //true

17 System.out.println(num1.equals(num2)); //true

18

19 Integer a = 1;20 Integer b = 2;21 Integer c = 3;22 Integer d = 3;23 Integer e = 300;24 Integer f = 300;25 Long g = 3L;26 Long h = 2L;27

28 Integer e1 = 100;29 Integer e2 = 200;30 int e3=100;31 int e4=200;32

33 System.out.println(c==d); //true, 没有疑问

34 System.out.println(e==f); //false, 超过范围-128~127,每次都重新new

35 System.out.println(e==f+0); //true, 如果有操作运算符,就是比较的值

36 System.out.println(c==(a+b)); //true

37 System.out.println(c.equals((a+b))); //true

38 System.out.println(g==(a+b)); //true //有操作运算符

39 System.out.println(g.equals((a+b))); //false//类型不一样

40 System.out.println(g.equals((a+h))); //true //自动提升类型

41 System.out.println(g==(a+h)); //true

42 System.out.println(e==(e1+e2)); //true

43 System.out.println(e.equals((e1+e2))); //true

44 System.out.println(e==(e1+e4)); //true

45 System.out.println(e.equals((e2+e3))); //true

46 }47 }

总结:

1:当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动  拆箱的过程)。

补充:"=="只有两个都是包装类型,并且没有操作运算,才是比较是否指向同一个对象。如果有一个是包装类型,另一个不是包装类型,则比较的就是值。

当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱

当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。

2:equal, 首先判断类型是否一样,如果一样,就看值是否相等。对于包装器类型,equals方法并不会进行类型转换。

下面是Integer中对equal进行重载:

1 public booleanequals(Object obj) {2 if (obj instanceofInteger) {3 return value ==((Integer)obj).intValue();4 }5 return false;6 }

line36由于  a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。

line37对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。

下面这个例子有点奇怪,自己也不是很了解,但是程序运行结果就是这样:会自动提升类型,所以相等

1 int e5 = 3;2 long e6 = 3;3 //Long e66 = 3;//编译失败Type mismatch: cannot convert from int to Long

4 Long e666=3L;5 Double e7 = 3.0;6 Integer e8 = 3;7

8 System.out.println(e5==e6); //true

9 System.out.println(e5==e666); //true

10 System.out.println(e5==e7); //true

11 System.out.println(e6==e7); //true, 一边是基础类型,一般是包装类,比较值

12 System.out.println(e6==e8); //true13 //System.out.println(e7==e8);//编译失败Incompatible operand types Double and Integer

到此处,应该对包装类和装箱,拆箱比较了解了,在遇见这样的题目应该没有问题了。

java装箱_Java 装箱 拆箱相关推荐

  1. java double 装箱_Java自动拆箱和装箱

    一.什么是装箱/拆箱 在讲之前,得先提一下为什么两个概念:基本数据类型及其包装类,我们都知道Java是一种面向对象的语言,但是Java中的基本数据类型是不面向对象的,这时在使用中便会存在诸多的不便,为 ...

  2. java 包装类缺点_Java 自动拆箱和自动装箱学习笔记

    Java 自动拆箱和自动装箱学习笔记 详情参考以下 1. 概述 Java 中的自动装箱和自动拆箱算是一种语法糖,也就是在编译阶段编译器在合适的情况下帮我们的做了自动拆箱和自动装箱. 众所周知,Java ...

  3. java自动装箱的好处_Java自动装箱、自动拆箱

    一.前言 Java自动装箱和自动拆箱是JDK5.0版本提供的新特性,所以在JDK5.0后的版本中都可以使用,之前的版本则不支持该特性. 理解自动装箱和自动拆箱需要先对java中的8种原始数据类型和相对 ...

  4. java中为什么自动装箱拆箱_Java自动装箱和自动拆箱的理解

    Java自动装箱和自动拆箱的理解 1.代码 public class AutoBoxing { public static void main(String[] args) { Integer a = ...

  5. java 自动装箱自动拆箱_自动装箱和自动拆箱

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

  6. 第三次学JAVA再学不好就吃翔(part64)--自动装箱和自动拆箱

    学习笔记,仅供参考 自动装箱和自动拆箱 装箱:把基本类型转换为包装类类型 int x = 100; Integer i1 = new Integer(x); 拆箱:把包装类类型转换为基本类型 int ...

  7. Java 进阶——自动装箱和自动拆箱

    1.什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象实例的时候,我们会这样: Class a ...

  8. 如何理解Java中的自动拆箱和自动装箱?

    小伟刚毕业时面的第一家公司就被面试官给问住了,记忆尤深啊- 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这-这-知识盲区- 回到家后小伟赶紧查资料,我透,这不就 ...

  9. java 自动装箱自动拆箱,java自动装箱、自动拆箱和正常情况性能比较

    自动装箱和自动拆箱是java5.0版本引入的,能自动将基本类型转换为对应的基本类型包装对象,那么我们比较一下他们的性能情况. package com.wmmad.test; import junit. ...

  10. java自动装箱和自动拆箱

    Java自动装箱和自动拆箱是Java语言的一颗语法糖. 下面说一下java的自动装箱和拆箱的例子 1. 深入理解java虚拟机上的一个例子 public static void testJvmBook ...

最新文章

  1. Javascript与正则表达式个人总结与收录--高级篇
  2. 年薪50万的程序员_这些年薪50万+的程序员都经历了什么?
  3. IOS7为什么遭吐槽?
  4. RH124 第六单元   管理物理存储
  5. hdu_1861_游船出租_201402282130
  6. 笔记-JavaWeb学习之旅4
  7. 你觉得人生最好的年龄段是哪段时间?
  8. 《Java8实战》-第五章读书笔记(使用流Stream-02)
  9. I00001 杨辉三角
  10. Spark2.x详解
  11. win7 操作mysql_win7系统如何设置Mysql密码保护数据库
  12. java+oracle+ojdbc14_请教:使用ojdbc5.jar作为驱动jar包无法正常连接oracle数据库,而使用ojdbc14.jar却可以正常连接?...
  13. ARP攻击实战以及防御手段
  14. The Journal of Neuroscience: 珠心算训练有助于提高儿童的视觉空间工作记忆
  15. 百度指数对网站优化有什么作用
  16. 微型计算机外部设备接口,第五章 微型计算机输入输出接口
  17. 验证哥德巴赫猜想(函数专题)
  18. DDD第3篇 - 事件风暴
  19. 《华为区块链白皮书》重磅发布(4大类应用场景/5分钟上链/)
  20. linux中wq和wq 的区别,wq+linux+wq什么意思

热门文章

  1. 13个VSCode使用技巧,开启高效的开发模式
  2. 解读华为云原生数据库设计原则,打破传统数据库上云瓶颈
  3. 99%的人都能看懂的分布式系统「补偿」机制
  4. 【华为云技术分享】低代码开发平台发展趋势:低代码——炒作还是趋势?
  5. 有了它,Python编码再也不为字符集问题而发愁了!
  6. javascript基础修炼(1)——一道十面埋伏的原型链面试题
  7. ceph怎么搭建文件存储_SUSE专家谈Ceph落地之最佳实践
  8. 红橙Darren视频笔记 流式布局tagLayout measure layout方法学习 adapter使用 学习感悟
  9. TikZ学习笔记(二)循环
  10. WORD如何一键转PPT