博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一道Integer面试题引发的对Integer的探究
阅读量:7071 次
发布时间:2019-06-28

本文共 5076 字,大约阅读时间需要 16 分钟。

  

面试题:

//在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
{ //...}

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。

 

转载于:https://www.cnblogs.com/demingblog/p/5626824.html

你可能感兴趣的文章
PHP接口&抽象类验证笔记
查看>>
Spark Streaming源码解读之No Receivers
查看>>
使用背景图的div宽高自适应
查看>>
sql注入工具
查看>>
MongoDB 开启用户认证登录
查看>>
ADO.NET操作数据库(一)
查看>>
指针与引用的本质区别
查看>>
Auto Layout 使用心得(五)—— 根据文字、图片自动计算 UITableViewCell
查看>>
M3U8在线视频文件下载合成MP4视频(自己想看电影)
查看>>
HTML5的布局的使用
查看>>
hdu 1068 二分图的最大匹配匈牙利算法
查看>>
一个IT人的非典型职场十年 (4)
查看>>
Netty之Recycler实现对象池
查看>>
Netty5入门学习笔记004-使用Netty传输POJO对象(上)
查看>>
Eclipse的快捷键总结
查看>>
RandomAccessFile相关(读写文件) --本文的正确性有待您验证。
查看>>
forward与redirect的区别
查看>>
实现SPF垃圾邮件防护功能
查看>>
Slave IO: Yes Slave SQL: No Seconds Behind Mast...
查看>>
eclipse 使用Maven deploy命令部署构建到Nexus上
查看>>