从一道选择题开始

分析

选项A

  选项A中比较的是i01和i02,Integer i01=59这里涉及到自动装箱过程,59是整型常量,经包装使其产生一个引用并存在栈中指向这个整型常量所占的内存,这时i01就是Integer 的引用。
  而int i02=59由于int是基本类型,所以不存在引用问题,直接由编译器将其存放在栈中,换一句话说,i02本身就是59。那么System.out.println(i01== i02)结果任何呢?这里涉及到了拆箱的过程,因为等号一边存在基本类型所以编译器后会把另一边的Integer对象拆箱成int型,这时等号两边比较的就是数值大小,所以是true。

好了,到了这里,你有没有想到这样一个问题:如果是Integer i01=59;Integer i02=59;然后System.out.println(i01== i02)的结果是?可能你会说比较数值大小所以相等啊,也有可能说等号两边对象引用,所以比较的是引用,又因为开辟了不同的内存空间,所以引用不同所以返回false。可是正确答案是:true.
再来看这个问题::如果是Integer i01=300;Integer i02=300;然后System.out.println(i01== i02)的结果是? 你可能说上面你不是说了true嘛,怎么还问这样的问题,可是这次的答案是false。你是否会吃惊?大牛除外,我是小白,求不打脸!

  解析:当靠想象无法解决问题的时候,这是就要看源代码了!!很重要!我们可以在Integer类中找到这样的嵌套内部类IntegerCache:

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) {
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);
}
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类装入内存中时,会执行其内部类中静态代码块进行其初始化工作,做的主要工作就是把一字节的整型数据(-128-127)装包成Integer类并把其对应的引用存入到cache数组中,这样在方法区中开辟空间存放这些静态Integer变量,同时静态cache数组也存放在这里,供线程享用,这也称静态缓存
  所以当用Integer 声明初始化变量时,会先判断所赋值的大小是否在-128到127之间,若在,则利用静态缓存中的空间并且返回对应cache数组中对应引用,存放到运行栈中,而不再重新开辟内存。
  所以对于Integer i01=59;Integer i02=59;**i01 和 i02是引用并且相等都指向缓存中的数据,所以返回true。而对于**Integer i01=300;Integer i02=300;因为其数据大于127,所以虚拟机会在堆中重新new (开辟新空间)一个 Integer 对象存放300,创建2个对象就会产生2个这样的空间,空间的地址肯定不同导致返回到栈中的引用的只不同。所以System.out.println打印出false。

B选项

  从上面的分析,我们已经知道Integer i01=59返回的是指向缓存数据的引用。那么Integer.valueOf(59)返回的是什么或者操作是什么呢?
  这个函数的功能就是把int 型转换成Integer,简单说就是装包,那他是新创建一个对象吗?还是像之前利用缓存的呢?有了之前的经验,肯定想到的是利用缓存,这样做既提高程序速度,又节约内存,何乐而不为?
来看一下源代码:

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);
}

很明显跟之前的思想一致,若在-128到127范围,直接返回该对象的引用,否则在堆中重新new 一个。
  到这,System.out.println(i01== i03)的结果毋庸置疑就是true.

选项C

  Integer.valueOf(59)返回的是已缓存的对象的引用,而Integer i04 = new Integer(59)是在堆中新开辟的空间,所以二者的引用的值必然不同,返回false,这道题呢就选C

选项D

  System.out.println(i02== i04) i02是整型变量,i04是引用,这里又用到了解包,虚拟机会把i04指向的数据拆箱为整型变量再与之比较,所以比较的是数值,59==59,返回true.

学习并转载自:https://blog.csdn.net/dawn_after_dark/article/details/74154338

对我很有帮助

感谢作者

对 Java Integer.valueOf() 的一些了解的更多相关文章

  1. java Integer.valueOf 和 Integer.parseInt 和 new Integer区别及注意事项

    先看一下下面的结果 1.System.out.println(127==127); //true , int type compare 2.System.out.println(128==128); ...

  2. JAVA中Integer.valueOf, parsetInt() String.valueOf的区别和结果

    先来看段代码 public class IntegerDemo { public static void main(String[] args) { String num = null; System ...

  3. Java面试题之Integer.valueOf(String s);采用了什么设计模式

    Integer.valueOf(String s);//采用了亨元设计模式: 亨元模式: 它是以一种“节约内存,提高性能”为出发点的设计模式,运用共享技术有效的支持大量细粒度对象的复用. 源码解析: ...

  4. Java中Integer.parseInt和Integer.valueOf,你还傻傻分不清吗?

    在Java的Integer类中,有Integer.valueOf(String s)和Integer.parseInt(String s)两个静态方法,他们都能够将字符串转换为整型,他们到底有什么区别 ...

  5. Java面试必看之Integer.parseInt()与Integer.valueOf()

    Integer.parseInt()和Integer.valueOf()都是将成为String转换为Int,但是为什么Java会提供两个这样的方法呢,他们如果是同样的操作,岂不是多此一举? 我们来深挖 ...

  6. 深挖的Java源代码之Integer.parseInt()vs Integer.valueOf()

    Integer.parseInt()和Integer.valueOf()都是用来将String转换为Int的,但是为什么Java会提供两个这样的方法呢,他们如果是同样的操作,岂不是多此一举? 我们来深 ...

  7. java面试基础题------》int Integer Integer.valueOf

    在jdk1.5的环境下,有如下4条语句: 1 2 3 4 Integer i01 = 59; int i02 = 59; Integer i03 =Integer.valueOf(59); Integ ...

  8. 【转】理解Java Integer的缓存策略

    本文将介绍 Java 中 Integer 缓存的相关知识.这是 Java 5 中引入的一个有助于节省内存.提高性能的特性.首先看一个使用 Integer 的示例代码,展示了 Integer 的缓存行为 ...

  9. Java Integer(-128~127)值的==和equals比较产生的思考

    最近在项目中遇到一个问题,两个值相同的Integer型值进行==比较时,发现Integer其中的一些奥秘,顺便也复习一下==和equals的区别,先通过Damo代码解释如下: System.out.p ...

随机推荐

  1. C++ STL标准模板库(queue)

    //queue的使用 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<queue> using name ...

  2. 第二百零九节,jQuery EasyUI,Pagination(分页)组件

    jQuery EasyUI,Pagination(分页)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Pagination(分页)组件的使 ...

  3. 第一百四十八节,封装库--JavaScript,菜单切换

    第一百四十八节,封装库--JavaScript,菜单切换 首先在封装库封装点击切换方法 /** dian_ji_qie_huan()方法,设置点击切换,将元素设置成点击切换,也就是点击目标元素后,循环 ...

  4. 【BZOJ】3396: [Usaco2009 Jan]Total flow 水流 (最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3396 裸的最大流跑过.. #include <cstdio> #include < ...

  5. Deep Networks for Image Super-Resolution with Sparse Prior

    深度学习中潜藏的稀疏表达 Deep Networks for Image Super-Resolution with Sparse Prior http://www.ifp.illinois.edu/ ...

  6. linux配置sftp用户的chroot步骤(用户的sftp根文件夹)

    1.编辑ssh中的sftp的配置,命令可能是:vi /etc/ssh/sshd_config 在这个文件里最后增加 #限制sftp组的用户使用sftp时在自己的home文件夹下 Match Group ...

  7. 报错An internal error occurred during: "reload maven project". java.lang.NullPointerException

    新建了一个maven项目,由于有问题就删除了,但是卡住了就强制关闭了. 查了一下是由于由于没有正常关机导致eclipse无法将数据正常写入配置文件导致无法启动.所以报这样一个异常. 最后是这样解决的: ...

  8. simpson公式求定积分(模板)

    #include<cstdio> #include<cmath> #include <algorithm> using namespace std; double ...

  9. oracle 实现多字段匹配一个关键字查询语句

    oracle 实现多字段匹配一个关键字查询语句:有两种方法(经测试,10g中不能用,11g才行): 第一种. select * from table where ('字段名1' ||'字段名2' || ...

  10. English Grammar

    What is Grammar?