一道Integer面试题引发的对Integer的探究
面试题:
//在jdk1.5的环境下,有如下4条语句: Integer i01 = 59;
int i02 = 59;
Integer i03 =Integer.valueOf(59);
Integer i04 = new Integer(59); 以下输出结果为false的是: A. System.out.println(i01== i02);
B. System.out.println(i01== i03);
C. System.out.println(i03== i04);
D. System.out.println(i02== i04);
1.题目中提到了,是Jdk1.5的环境。
OK,我们新建一个项目,新建一个类,把代码复制进去。将Java Compiler设置为1.5. 关于这个版本的问题稍后再谈。
2.这里有两个数据类型,int和Integer。
int为基本类型。
Integer为对象类型。Integer的类声明是这样的:
public final class Integer extends Number implements Comparable<Integer> {
//...
}
1、Integer类是final的,不能被继承
2、Integer类实现了Comparable接口,所以可以用compareTo进行比较。
3、Integer继承了Number类,所以该类可以调用longValue、floatValue、doubleValue等系列方法返回对应的类型的值。
3.题目中声明了三个Integer变量,i01,i03,i04.这三种声明方式有啥区别呢?
3.1 Integer i04 = new Integer(59); 做了什么?
看源码,这个构造函数是这样的:
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value; /**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
new Integer(59)的这个操作,调用了构造函数,将59这个值,赋给了Integer的局部变量value。
3.2 Integer i03 = Integer.valueOf(59); //这个 Integer.valueOf 方法又做了什么??
看Integer.valueOf源码:
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这里,valueOf方法先判断传入参数的值,满足if 条件的话,则返回cache值。
否则 new 一个Integer 返回。这里的 if中的条件 IntegerCache.high=127, IntegerCache.low=-128;从IntegerCache的类定义可以看出,IntegerCache里边定义了一个数组cache用来存储Integer对象,静态块里边完成了数组的初始化,存入了-128到127之间的Integer对象:
private static class IntegerCache {//这个类是 Integer 类的 静态内部类。看这个代码不难发现,在Integer加载之后这个内部类的cache数组里边就初始化了-128到127之间的值
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) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
所以,对于Integer.valueOf(i)方法 , 当i在-128-127之间时返回的是缓存的Integer对象。 否则返回的是一个新的Integer对象。
这里传递的是59,所以返回的是cache里边的对象。
3.3 Integer i01 = 59;// 这句话又做了什么?
我们将源码产生的class文件反编译发现如下:
源码:
public static void main(String[] args) {
// TODO Auto-generated method stub Integer i01 = 59;// Integer.valueOf(59);
int i02 = 59;
Integer i03 = Integer.valueOf(59);
Integer i04 = new Integer(59);
System.out.println("i01 == i02:" + (i01 == i02));
System.out.println("i01 == i03:" + (i01 == i03));
System.out.println("i03 == i04:" + (i03 == i04));
System.out.println("i02 == i04:" + (i02 == i04)); }
反编译之后:
public static void main(String[] args)
{
Integer i01 = Integer.valueOf(59);
int i02 = 59;
Integer i03 = Integer.valueOf(59);
Integer i04 = new Integer(59);
System.out.println("i01 == i02:" + (i01.intValue() == i02));
System.out.println("i01 == i03:" + (i01 == i03));
System.out.println("i03 == i04:" + (i03 == i04));
System.out.println("i02 == i04:" + (i02 == i04.intValue()));
}
可以发现:Integer i01=59;在反编译过来之后是Integer.valueOf(59);
在用Integer 类型的i01和int类型的i02进行“==”比较的时候,反编译过来的是:i01.intValue() == i02
这两个操作分别为 自动装箱 和自动拆箱。这个特性是在java1.5开始才有的。所以第一点中提到了jdk版本为1.5.
如果我们在eclipse/myeclipse 中将java compiler设置成1.5以下的就会无法通过编译:
Type mismatch: cannot convert from int to Integer


通过上面的分析,这题就不难得出答案了。
i01 == i02 等价于 i01.intValue()==i02 两个值的比较59==59 -->true;
i01 == i03 由于 59在-128到127之间,所以,i01和i03的赋值操作返回的是同一个对象。都是从chche中返回的同一个对象,对象地址相同 true;
i03 == i04 i03是来自缓存值,i04是新new的对象 ,二者不是同一个对象,所以false。
i02 == i04 和第一个类似,true。
一道Integer面试题引发的对Integer的探究的更多相关文章
- 一道python面试题引发的血案
这里说的是一道阿里校招的面试题:一行代码实现对列表a中的偶数位置的元素进行加3后求和? 今天去面试同样遇到了这个题目,这道题考察的是对python高阶函数map/filter的灵活运用(具体的使用方法 ...
- 一道JS面试题引发的血案
刚入职新公司,属于公司萌新一枚,一天下午对着屏幕看代码架构时. BI项目组长给我看了一道面试别人的JS面试题. 虽然答对了,但把理由说错了,照样不及格. 话不多说,直接上题: var a = 1; s ...
- 一道Javascript面试题引发的血案
文章首发于szhshp的第三边境研究所,转载请注明 先来看几道面试题,公司的开发们都尝试做了一下,然而基本没有人能够全部答对. 覆盖的考点很多,也有一些难度,题目挺有意思建议手动执行一边玩玩. Que ...
- 一道面试题引发的对 Java 内存模型的一点疑问
一道面试题引发的对Java内存模型的一点疑问 问题描述 如上图所示程序,按道理,子线程会通过 num++ 操作破坏 while 循环的条件,从而终止循环,执行最后的输出操作.但在我的多次运行中,偶尔会 ...
- 由自动装箱和拆箱引发我看Integer源码
背景和问题 在看别人整理的资料时,看到如下一段代码: package com.sitech.test; /** * 自动装箱和拆箱 jdk1.6 * @author liaowp * */ publi ...
- java面试题之int和Integer的区别
int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...
- 一道JS面试题所引发的"血案",透过现象寻本质,再从本质看现象
觉得本人写的不算很烂的话,可以登录关注一下我的GitHub博客,新手写东西写的不好之处,还望见谅,毕竟水平有限,写东西只为交流提高,一起学习,还望大神多加指点,指出纰漏,和提出宝贵的意见,博客会坚持写 ...
- 一道 JavaScript 面试题
有一道 JavaScript 面试题. f = function () { return true; }; g = function () { return false; }; (function() ...
- 一道sql面试题(查询语句)
一道sql面试题(查询语句) id name age 1 a 11 2 b 11 3 c 12 4 d 13 5 e ...
随机推荐
- FileItem类的常用方法
FileItem类的常用方法: 1. boolean isFormField() isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果 ...
- fiddler如何修改request header
在命令行中输入命令: bpu www.baidu.com (这种方法只会中断www.baidu.com) 然后刷新网站,在fiddler中点击被打断的网址,点击Inspectors—>Ra ...
- Mybatis框架基于注解的方式,实对数据现增删改查
编写Mybatis代码,与spring不一样,不需要导入插件,只需导入架包即可: 在lib下 导入mybatis架包:mybatis-3.1.1.jarmysql驱动架包:mysql-connecto ...
- Arduino学习经验(一)之解决舵机库和pwm输出冲突
一.前言 最近在公司学习Arduino uno ,用它实现小车超声波避障功能.实现的功能很简单,就是在小车前方挂一个超声波模块,当碰到障碍物时,会通过舵机进行摆头,判断两边的距离,进行左右转弯.但是碰 ...
- lua 和 c/c++ 交互 (持续更新)
参考: http://blog.csdn.net/xiaohuh421/article/details/7476485 http://blog.csdn.net/shun_fzll/article/d ...
- Eclipse+maven+scala2.11.8+spark2.0.0的环境部署
主要在maven-for-scalaIDE纠结了,因为在eclipse版本是luna4.x 里面有自己带有的maven. 根据网上面无脑的下一步下一步,出现了错误,在此讲解各个插件的用途,以此新人看见 ...
- Qt on Android 蓝牙开发
版权声明:本文为MULTIBEANS ORG研发跟随文章,未经MLT ORG允许不得转载. 最近做项目,需要开发安卓应用,实现串口的收发,目测CH340G在安卓手机上非常麻烦,而且驱动都是Java版本 ...
- Android first --- 单元测试框架junit
#单元测试junit* 定义一个类继承AndroidTestCase,在类中定义方法,即可测试该方法 * 在指定指令集时,targetPackage指定你要测试的应用的包名 <instrumen ...
- 创建EF数据模型
最后的应用程序,看上去就像下边这样: 创建数据模型,你将从以下三个类开始: 在Models文件夹,新建以下类: using System; using System.Collections.Gener ...
- nginx+lua实现简单的waf网页防火墙功能
原文:http://www.2cto.com/net/201608/534272.html 安装LuaJIT http://luajit.org/download/LuaJIT-2.0.4.tar.g ...