java常量池中基本数据类型包装类的小陷阱
想必大部分学过java的人都应该做过这种题目:
public class Test {
public static void main(String[] args) {
//第一个字符串
String s1="hello"; //第二个字符串
String s2="hello"; //比较s1和s2是否相同
System.out.println(s1==s2); /**
* 修改变量
*/ s1=new String("hello"); s2=new String("hello"); //再次比较s1和s2是否相同
System.out.println(s1==s2);
}
};
最后的结果如图:
图一
对于这个结果,我相信没有人有异议!因为第一组是依靠常量池的结果,即String s1=“hello”时实际会在内存中栈的常量池中创建一个字符串常量“hello”对象,当String s2=“hello”时,因为常量池中已经存在,所以s2会直接指向同一个”hello“对象,也就是s1和s2对象的地址值是一致的,此时的String就有点类似与基本数据类型,所以用“==”来比较的时候,值为“true”。
而如果String s1=new String("hello")时,s1在堆中开辟出新的内存空间存放“hello”值,同理,s2也会在堆中重新开辟空间存放“hello”值,s1和s2所指向的值的地址不同,用“==”来比较的时候自然是不同的,值为“false”。
但不知道有多少人做过下面这道题目呢?
修改一下上题中的变量类型为Integer。
package action; public class Test {
public static void main(String[] args) {
//第一个数值
Integer s1=127; //第二个数值
Integer s2=127; //比较s1和s2是否相同
System.out.println(s1==s2); /**
* 修改变量
*/ s1=128; s2=128; //再次比较s1和s2是否相同
System.out.println(s1==s2);
}
};
你的答案会是什么呢?
结果图如下:
图二
是不是有点出乎你的意料呢?
从原理上来说,Integer和String类型都属于引用类型,那么最后的结果应该和String类型的比较一致,而且就算Integer类型的没有常量池技术那么这两次的结果也应该一致啊,毕竟只是相差1而已!
这就是我这篇博客要说的java常量池的小陷阱了!
java中的基本数据类型的包装类有6种实现了常量池技术,他们分别是:Byte , Short,Integer,Long ,Characher ,Boolean。Double和Float没有实现,佐证如下图:
图三
直接定义常量是会报错的(这个佐证其实有点不靠谱,如果有谁知道,麻烦告诉一声,谢谢!)
这5种包装类在常量池的实现上与String有点区别,以Integer为例,当有Integer i=127时,实际上发生了如下操作:
Integer i=Integer.valueOf(127)
Integer.valueOf()方法基于减少对象创建次数和节省内存的考虑,缓存了[-128,127]之间的数字。此数字范围内传参则直接返回缓存中的对象。在此之外,直接new出来.
而在上述所说的6种有常量池技术的包装类中,除了Boolean以外,其他的值都不能超过 127 (小于或者等于) ,超过127常量池就不予自动创建对象,这时包装类就和普通的引用类型没有区别了。
关于常量池的详细介绍,可以借鉴这篇博客(我也是从中得到原因的):
http://www.cnblogs.com/qinqinmeiren/archive/2011/07/19/2151683.html
关于Integer.valueOf()可以参考这篇:
http://blog.csdn.net/randyjiawenjie/article/details/7603427
java常量池中基本数据类型包装类的小陷阱的更多相关文章
- 【转载】Java常量池
本篇随笔为转载,原贴地址:Java常量池理解与总结. (其实Java的常量池有点像C++中的存储字符串常量的常量存储区). 一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法 ...
- java常量池
Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newarray. anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回 ...
- Java基础知识强化103:Java常量池理解与总结
一.相关概念 1. 什么是常量 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. 2. Class文件中的 ...
- java常量池概念
在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...
- java常量池詳解
一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池在Clas ...
- java虚拟机学习-Java常量池理解与总结(13-2)
一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池在Clas ...
- Java常量池的理解
1.常量池的好处常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享.例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中.(1)节省内存空间:常量池中所有相同的字符串常 ...
- [转]java常量池理解总结
一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池在Clas ...
- java 常量池
在jvm规范中,每个类型都有自己的常量池.常量池是某类型所用常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型.字段.方法的符号引用.之所以是符号引用而不是像c语言那样,编译时直接 ...
随机推荐
- ES6中的迭代器(Iterator)和生成器(Generator)
前面的话 用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简 ...
- 基于Vivado调用ROM IP core设计DDS
DDS直接数字式频率合成器(Direct Digital Synthesizer) 下面是使用MATLAB生成正弦波.三角波.方波的代码,直接使用即可. t=:*pi/^:*pi y=0.5*sin ...
- CentOS 访问 Windows 共享目录
起因 由于公司的网络切换后,将所有的服务器都切换到了指定的网段(工作电脑在一个网络,服务器在另一个网络:这样一来,不同部门的 work stations 可以彼此访问,不同部门的服务器(servers ...
- 使用ide编程时候 不知为何突然光标变宽,如何恢复成原有的细竖光标
各位朋友们, 你们在编程时候有没有这样的情况: 码着码着,突然不知什么原因,光标变成这样了: 这种宽的光标,不知道怎么调都调不回去,而且网上也没有类似的问题描述 就对我们编程极其不便(因为这种光标是操 ...
- python爬取百度搜索结果ur汇总
写了两篇之后,我觉得关于爬虫,重点还是分析过程 分析些什么呢: 1)首先明确自己要爬取的目标 比如这次我们需要爬取的是使用百度搜索之后所有出来的url结果 2)分析手动进行的获取目标的过程,以便以程序 ...
- Linux入门基础知识
注:内容系兄弟连Linux教程(百度传课:史上最牛的Linux视频教程)的学习笔记. Linux入门基础知识 1. Unix和Linux发展历史 二者就像父子关系,当然Unix是老爹.1965年,MI ...
- 某安寿险HR核人面试问题总结,技术面波澜不惊,HR面反而有被暴击感
之前朋友推荐了某安寿险的技术类职位.经过IQ/EQ网上笔试,技术面之前的java基础笔试和技术面试,基本上没什么意外的.昨天晚上7点安排的HR核人面试(他们的人力部门的工作负荷比较大,目前这个部门处于 ...
- 报错:No identifier specified for entity: main.java.com.sy.entity.User的解决办法
自己也没怎么搭建过框架,更何况还是spring mvc的,最近在带两个实习生,正好教他们怎么搭建一个spring mvc的框架,然而我在映射表的时候,提示报错了. 实体基类: public class ...
- 关于DB2版本、补丁升级和回退的总结[转载]
首先介绍几个概念 RELEASE的升级就是版本升级,例如9.1→9.5→9.7→10.1,可以跳版本升级,例如9.1→10.1 FIX PACK简称FP,就是打补丁,例如9.7.1→9.7.2,每个版 ...
- cnblogs博客自定义
我使用的是博友分享的CCS设计:http://www.cnblogs.com/libaoheng/archive/2012/03/19/2406836.html CSS定制页面风格 /*公用*/ bo ...