[转]Integer.valueOf(String) 方法之惑
具体问题以前偶然遇到过,好象是一个java答题得分的论坛,当时做错还研究了下怎么回事,但是前两天遇到类似问题却没想起来。巩固下基础,转了下面文章。
以下内容转自:http://www.importnew.com/9162.html
-------------分割线----------------------
有个仁兄在 StackOverflow 上发起了一个问题,是这么问的:
“ 我被下面的代码搞晕了,为什么它们会返回不同的值?”
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
输出是:
true
false
true
为什么第一个判断返回了true而第二个判断返回了false?127和128有什么我不知道的区别吗?(当然除了127小于128…)
还有,为什么第三个判断返回了true?
我看了另一个相关提问的回答,但是我还是不知道它们什么时候返回true还有为什么第二个判断返回false。
回答#1:
Integer.valueOf(String)确有一个不同寻常的行为。
valueOf会返回一个Integer(整型)对象,当被处理的字符串在-128和127(包含边界)之间时,返回的对象是预先缓存的。这就是为什么第一行的调用会返回true-127这个整型对象是被缓存的(所以两次valueOf返回的是同一个对象)——第二行的调用返回false是因为128没有被缓存,所以每次调用,都会生成一个新的整型对象,因此两个128整型对象是不同的对象。
重要的是你要知道在上面的比较中,你实际进行比较的是integer.valueOf返回的对象引用,所以当你比较缓存外的整型对象时,相等的判断不会返回true,就算你传个valueOf的值是相等的也没用。(就像第二行中Integer.valueOf(128)==Integer.valueOf(128))。想让这个判断返回true,你需要使用equals()方法。
parseInt()返回的不是整型对象,而是一个int型基础元素。这就是为什么最后一个判断会返回true,第三行的判断中,在判断相等时,实际比较的是128 == 128,所以它必然是相等的。
再来说说第三种比较中的一点区别,使得它的结果与第二种比较不一样了:
一个unboxing conversion(一种比较时的转换,把对对象的引用转换为其对应的原子类型)在第三行的比较中发生了。因为比较操作符使用了==同时等号的两边存在一个int型和一个Integer对象的引用。这样的话,等号右边返回的Integer对象被进一步转换成了int数值,才与左边进行相等判断。
所以在转换完成后,你实际比较的是两个原子整型数值。这种转换正是你在比较两个原子类型时所期待看到的那样,所以你最终比较了128等于128。
回答#2:
Integer类有一个静态缓存,存储了256个特殊的Integer对象——每个对象分别对应`-128 和127之间的一个值。
有了这个概念,就可以知道上面三行代码之间的区别。
new Integer(123);
显示创建了一个新的Integer对象。
Integer.parseInt("123");
解析完字符串后返回一个int值。
Integer.valueOf("123");
这种情况比其他的要更复杂一些。首先进行了字符串解析,然后如果解析的值位于-128和127之间,就会从静态缓存中返回对象。如果超出了这个范围,就会调用Integer()方法并将解析的值作为参数传入,得到一个新的对象。
现在,让我们看一下问题中的3个表达式。
Integer.valueOf("127")==Integer.valueOf("127");
上面的表达式返回true,因为Integer的值从静态缓存中取了2次,表达式返回了对象与自己比较的结果。因为只有一个Integer对象,所以返回结果为true。
Integer.valueOf("128")==Integer.valueOf("128");
上面的表达式返回false,因为128没有存在静态缓冲区。所以每次在判断相等时等式两边都会创建新的Integer对象。由于两个Integer对象不同,所以==只有等式两边代表同一个对象时才会返回true。因此,上面的等式返回false。
Integer.parseInt("128")==Integer.valueOf("128");
上面的表达式比较的是左边的原始int值128与右边新创建的Integer对象。但是因为int和Integer之间比较是没有意义的,所以Java在进行比较前会将Integer自动拆箱,所以最后进行的是int和int值之间的比较。由于128和自己相等,所以返回true。
-------------------------分割线------------------------
原文链接: stackoverflow 翻译: ImportNew.com- 靳禹
译文链接: http://www.importnew.com/9162.html
[转]Integer.valueOf(String) 方法之惑的更多相关文章
- Integer.valueOf(String) 方法之惑
本文由 ImportNew - 靳禹 翻译自 stackoverflow.欢迎加入翻译小组.转载请见文末要求. 有个仁兄在 StackOverflow 上发起了一个问题,是这么问的: “ 我被下面的代 ...
- Integer.valueof(String s)和Integer.parseInt(String s)的具体区别是什么?
Integer.valueof(String s)和Integer.parseInt(String s)的具体区别是什么? Integer.valueof(String s)是将一个包装类是将一个实际 ...
- Integer.parseInt(String s) 和 Integer.valueOf(String s) 的区别
通过查看java.lang.Integer的源码可以发现, 它们最终调用的都是 /** * Parses the string argument as a signed integer in the ...
- Java面试题之Integer.valueOf(String s);采用了什么设计模式
Integer.valueOf(String s);//采用了亨元设计模式: 亨元模式: 它是以一种“节约内存,提高性能”为出发点的设计模式,运用共享技术有效的支持大量细粒度对象的复用. 源码解析: ...
- Integer和String "+""=="方法的不同
在上面的两个篇博客中,我们看到String和Integer不同的常量池的变现形式 我们再看一个例子: public static void main(String[] args) { // TODO ...
- 区分Integer.getInteger和Integer.valueOf、Integer.parseInt() 的使用方法
Integer类有两个看起来很类似的静态方法,一个是Integer.getInteger(String),另外一个是Integer.valueOf(String).如果只看方法名称的话,很容易将这两个 ...
- Integer.parseInt()和Integer.valueOf()方法详解
1.Integer.parseInt(): public static int parseInt(String s) throws NumberFormatException { return par ...
- Java中Integer类的方法
java.lang 类 Integer java.lang.Object java.lang.Number java.lang.Integer 全部已实现的接口: Serializable, Comp ...
- java Integer.valueOf 和 Integer.parseInt 和 new Integer区别及注意事项
先看一下下面的结果 1.System.out.println(127==127); //true , int type compare 2.System.out.println(128==128); ...
随机推荐
- Python基础学习笔记(三)运算符
参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-chinese-encoding.html 3. http://w ...
- Android中序列化对象到XMl 和 XML反序列化为对象
package com.example.xmloperation; import java.io.File; import java.io.FileOutputStream; import java. ...
- QQ游戏_相关
1. 侍魂: 1.1. ...\QQGame ...\QQGame\samsho2 1.2. C:\Users\xx\AppData\Roaming\Tencent\QQGAME\Download C ...
- ajax学习笔记(原生js的ajax)
ajax是一个与服务器端语言无关的技术,可以使用在任何语言环境下的web项目(如JSP,PHP,ASP等). ajax优点: 1) 页面无刷新的动态数据交互 2) 局部刷新页面 3) 界面的美观 4) ...
- 关于jQuery的小知识点
jQuery 简介 jQuery 库可以通过一行简单的标记被添加到网页中. jQuery 库 - 特性 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML ...
- (四)Ubuntu 14.04 文件服务器--samba的安装和配置
samba是Linux系统上的一种文件共享协议,可以实现Windows系统访问Linux系统上的共享资源,现在介绍一下如何在Ubuntu 14.04上安装和配置samba一. 一.更新源列表 打开&q ...
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
Android 高手进阶(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...
- Eclipse安装SVN插件总结
1.下载最新的Eclipse,我的版本是3.7.2 indigo(Eclipse IDE for Java EE Developers)版 如果没有安装的请到这里下载安装:http://ecli ...
- opencl初探-sobel检测
sobel检测的C版本,neon和GPU的时间比较. Platform: LG G3, Adreno 330 ,img size 3264x2448 sobel: C code neon GPU 73 ...
- Hbase之进行批处理操作
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...