面试题

如果之前学习过自动装箱的知识,可以先做下面几道面试题,帮助我们发现自己的知识盲点。如果你没有了解过自动装箱,可以先跳到后面阅读知识点总结部分,再回来做题。

面试题一

public void test() {//1 int a = 100;Integer b = 100;System.out.println(a == b);// true//2Integer c = 100;Integer d = 100;System.out.println(c == d);// true//3   c = 200;d = 200;System.out.println(c == d);// false
}
  • 第1段代码,基础类型a与包装类b进行==比较,这时b会拆箱,直接比较值,所以答案会打印 true
  • 第2段代码,两个包装类型变量都被赋值了100,所以根据我们之前的解析,这时会进行装箱,调用Integer的valueOf方法,生成2个Integer对象,引用类型==比较,直接比较对象指针,因为默认Integer cache 的下限是-128,上限默认127,这个范围的Integer会被缓存,所以在这里是同一个对象。答案为打印 true。
  • 跟上面第2段代码类似,只不过赋值变成了200,不在Integer的缓存范围,所以并不是同一个对象了。答案为打印 false

面试题二

  public static void main(String[] args) {Double i1 = 100.0;Double i2 = 100.0;Double i3 = 200.0;Double i4 = 200.0;System.out.println(i1==i2);//falseSystem.out.println(i3==i4);//false}

在这里解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单,因为在某个范围内的整型数值的个数是有限的,而浮点数却不是。也就是说,Double和Float的valueOf方法始终返回新对象

注意:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。Double、Float的valueOf方法的实现是类似的。

面试题三

面试题三涉及的知识点在上面都介绍过了,先尝试一下不看答案的情况下,自己能全部回答正确吗。

Integer a=1;
Integer b=2;
Integer c=3;
Integer d=3;
Integer e=321;
Integer f=321;
Long g=3L;
System.out.println(c==d);
System.out.println(e==f);
System.out.println(c==(a+b));
System.out.println(c.equals(a+b));
System.out.println(g==(a+b));
System.out.println(g.equals(a+b));

答案:

true
false
true
true
true
false

知识点总结

拆箱与装箱的缓存问题

  • 整型(Byte,Short,Integer,Long)会检查该数字是否在1个字节可表示的有符号整数范围内(-128~127),是则返回缓存对象,否则返回新对象。
  • Character会缓存整型值为0~127的字符,同样会检查字符是否落在缓存范围中,是则返回,否则返回新对象。
  • Double和Float的valueOf方法始终返回新对象。

触发自动装箱或拆箱的场景

  • 进行 = 赋值操作(装箱或拆箱)
  • 进行+,-,*,/混合运算 (拆箱)
  • 进行>,<,==比较运算(拆箱)
    • 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象
    • 而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
  • 调用equals进行比较(装箱)
  • ArrayList,HashMap等集合类 添加基础类型数据时,因为集合只能添加引用类型(装箱)

装箱与拆箱的实现原理

以Float为例

  • 调用了Float类的静态 valueOf方法,进行装箱
  • 调用了Float的floatValue方法,进行拆箱

自动装箱的性能问题

自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,会创建多余的对象,影响程序的性能。

Integer sum = 0;
for(int i=1000; i<5000; i++){  sum+=i;
}

上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下

int result = sum.intValue() + i;
Integer sum = new Integer(result);

由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。

因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作。

  • 自动装箱会创建多余对象,影响性能
  • 自动装箱成包装类型,需要记得判空,否则容易出现空指针异常

补充:基本类型和包装类型的使用场景

  • 集合类使用时只能使用包装类型。
  • 如果允许null值,则必然要用封装类
  • 用到泛型和反射调用函数,就需要用包装类
  • 其他情况下,最好使用基本类型,能避免自动装箱(需要new对象)的性能消耗,特别是在循坏中使用包装类型自动装箱会new出很多对象

关于自动装箱的这几道面试题,你都能答对吗?相关推荐

  1. java装箱_Java基础 【自动装箱和拆箱、面试题】

    JDK 1.5 (以后的版本)的新特性自动装箱和拆箱 1. 自动装箱:把基本类型转换为包装类类型 int a =10; Integer i = new Integer(a); Integer valu ...

  2. 网络基础——100道面试题,你能答对多少?

    文章目录 1.网站登陆缓慢是什么原因? 2.a与b服务器不在同一网段怎么设置?设置完还ping不通怎么排查? 3.在AB两台服务器之间通过一个服务器c做软路由使用给路由器c配置两块网卡并开启自身的路由 ...

  3. 自动装箱和拆箱的原理

    自动装箱和拆箱的原理 我们在面试中经常会被问到什么是自动装箱和拆箱,今天,我就通过代码来讲解一下自动装箱背后的原理 学过Java的都知道,自动装箱呢,就是将基本数据类型自动转换成Integer.Cha ...

  4. Java进阶之自动拆箱与自动装箱

    序. java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型 大小 范围 默认值 byte 8 -128 - 127 0 short 16 -32768 - 32768 0 ...

  5. Java中的自动装箱和拆箱

    自动装箱和拆箱 自动装箱和拆箱 自动装箱: 拆箱 1. 为什么要有包装类(或封装类) 2. 基本数据类型与对应的包装类: 3. 类型间的转换 4. 何时发生自动装箱和拆箱 赋值.数值运算时 方法调用时 ...

  6. java自动装箱性能

    2019独角兽企业重金招聘Python工程师标准>>> Java 的基本数据类型(int.double. char)都不是对象.但由于很多Java代码需要处理的是对象(Object) ...

  7. Java自动装箱/拆箱 - Java那些事儿

    昨天Java基本数据类型和引用类型一文中漏了几张图,已经补上,需要的自己回头去看,本系列文章首发于公众号:saysayJava. 在让人疑惑的Java代码 - Java那些事儿 一文中我们说到编译器自 ...

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

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

  9. java的自动装箱和拆箱,Java中的自动装箱和拆箱是什么?

    当我们用任何语言编写程序时,大多数时候我们使用原始数据类型,.但是,在面向对象编程领域,有些情况下原始数据类型会出现不足,而Java就是其中之一.为了克服原始数据类型的缺点,我们 当我们用任何语言编写 ...

最新文章

  1. 李飞飞团队最新论文:基于anchor关键点的类别级物体6D位姿跟踪
  2. HDU 1853 Cyclic Tour
  3. 基于python的快速傅里叶变换FFT(二)
  4. 在特定索引处插入字符串
  5. centos mysql压缩文件直接恢复_Centos下mysql数据库备份与恢复的方法
  6. okhttp进行网络传输文件
  7. 那传说中的P、NP以及NPC问题
  8. 饿了么多活利器:实时双向复制工具(DRC)
  9. Boost.Function 库示例
  10. SAP UI5 busy Dialog debug - 单步调试
  11. 第69课 胡萝卜与骨头
  12. java枚举类型特点_必须了解的高阶JAVA枚举特性!
  13. 1号店案例html源码_手把手教一起写jQuery版mini源码,分析jQuery的优势
  14. 如何将win10的资源管理器指向“这台电脑”?
  15. 机器学习库线性回归代码_PyCaret回归:更好的机器学习库
  16. 写一个自动阅读的方法(需要运用html和css和JavaScript)
  17. 如何反编译dll文件
  18. [AndroidO] [RK3399] -- 支持 CH341 驱动 -- 驱动模块的标准添加流程
  19. 计算机网络教室学生守则,高中计算机网络教室公益性开放管理制度
  20. wps将批量数字转换成条形码_WPS怎么批量制作条码.

热门文章

  1. IE 8兼容:X-UA-Compatible的解释
  2. uni-app uni-fab 修改图标
  3. Introduction to 3D Object Detection with Lidar
  4. 广告费的分摊计提 预提?NO
  5. 网络安全-常见面试题(Web、渗透测试、密码学、Linux等)
  6. Android -- 每日一问:如何设计一个照片上传 app ?
  7. 成熟敏捷组织中管理者的角色是咋样的?
  8. c++心形编码_c语言心形告白代码实现
  9. 在 Python 中将秒转换为小时、分钟和秒
  10. ORACLE忘记某个用户密码,但是密码已经过期了怎么办?