java 常量池
在jvm规范中,每个类型都有自己的常量池。常量池是某类型所用常量的一个有序集合,包括直接常量(基本类型,String)和对其他类型、字段、方法的符号引用。之所以是符号引用而不是像c语言那样,编译时直接指定其他类型,是因为java是动态绑定的,只有在运行时根据某些规则才能确定具体依赖的类型实例,这正是java实现多态的基础。
为了对常量池有更具体的认识,下面引用几个例子:
1,常量池中对象和堆中的对象
public class Test{
Integer i1=new Integer(1);
Integer i2=new Integer(1);
//i1,i2分别位于堆中不同的内存空间
System.out.println(i1==i2);//输出false
Integer i3=1;
Integer i4=1;
//i3,i4指向常量池中同一个内存空间
System.out.println(i3==i4);//输出true
//很显然,i1,i3位于不同的内存空间
System.out.println(i1==i3);//输出false
}
2,8种基本类型的包装类和对象池
java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象。以下是一些对应的测试代码:
public class Test{
public static void main(String[] args){
//5种整形的包装类Byte,Short,Integer,Long,Character的对象,
//在值小于127时可以使用常量池
Integer i1=127;
Integer i2=127;
System.out.println(i1==i2)//输出true
//值大于127时,不会从常量池中取对象
Integer i3=128;
Integer i4=128;
System.out.println(i3==i4)//输出false
//Boolean类也实现了常量池技术
Boolean bool1=true;
Boolean bool2=true;
System.out.println(bool1==bool2);//输出true
//浮点类型的包装类没有实现常量池技术
Double d1=1.0;
Double d2=1.0;
System.out.println(d1==d2)//输出false
}
}
3,String也实现了常量池技术
String类也是java中用得多的类,同样为了创建String对象的方便,也实现了常量池的技术,测试代码如下:
public class Test{
public static void main(String[] args){
//s1,s2分别位于堆中不同空间
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1==s2)//输出false
//s3,s4位于池中同一空间
String s3="hello";
String s4="hello";
System.out.println(s3==s4);//输出true
}
}
4.字符串比较更丰富的一个例子
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }
produces the output:
true true true true false true
输出结果的分别解释如下:
在同包同类下,引用自同一String对象.
在同包不同类下,引用自同一String对象.
在不同包不同类下,依然引用自同一String对象
在编译成.class时能够识别为同一字符串的,自动优化成常量,所以也引用自同一String对象
在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象
String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回一个引用,没有则添加自己的字符串进进入常量池,
注意,只是字符串部分,
所以这时会存在2份拷贝,常量池的部分被String类私有持有并管理,自己的那份按对象生命周期继续使用.
java 常量池的更多相关文章
- 触摸java常量池
java常量池是一个经久不衰的话题,也是面试官的最爱,题目花样百出,小菜早就对常量池有所耳闻,这次好好总结一下. 理论 小菜先拙劣的表达一下jvm虚拟内存分布: 程序计数器是jvm执行程序的 ...
- 【转载】Java常量池
本篇随笔为转载,原贴地址:Java常量池理解与总结. (其实Java的常量池有点像C++中的存储字符串常量的常量存储区). 一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法 ...
- java常量池概念
在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...
- java常量池理解
String类两种不同的创建方式 String s1 = "zheng"; //第一种创建方式 String s2 = new String("junxiang" ...
- java常量池中基本数据类型包装类的小陷阱
想必大部分学过java的人都应该做过这种题目: public class Test { public static void main(String[] args) { //第一个字符串 String ...
- java虚拟机学习-触摸java常量池(13-1)
java虚拟机学习-深入理解JVM(1) java虚拟机学习-慢慢琢磨JVM(2) java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制 java虚拟机学习-JVM内存管理:深 ...
- java常量池概念 (转)
在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...
- Java常量池详细说明
java常量池技术 java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多时间.常量池 ...
- 浅析Java常量池
Java常量池 Java常量池其实分为两种:静态常量池和运行时常量池 1.静态常量池 所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类. ...
- java常量池存放在哪里
运行以下方法: public class Test { public static void main(String[] args) { String str = "abc"; c ...
随机推荐
- c语言学习之基础知识点介绍(十四):指针的进阶
一.指针的加.减法运算 /* 1.加法运算 1).可以跟整数进行加法运算,得到的还是一个地址 公式: 地址 + 1 = 地址 + 1 * 类型所占的字节数 地址 + n = 地址 + n * 类型所占 ...
- Sublime Text2配置python环境
1.下载python并安装 地址:https://www.python.org/downloads/ 2.下载Sublime Text2 并安装 地址:http://www.subli ...
- C# Flash 图片上传案例(结合网上腾讯头像上传Flash插件)
之前遇到过很多次要上传类似头像图片这种功能需求,这次是要求弄一个flash插件上传图片 感谢主,一个偶然机会在网上找到了一个很好的腾讯头像修改的flash插件:插件下载 这个功能采用Ajax访问支持, ...
- 最近在学习UDP方面的通信,找到一个很棒的博客
http://blog.csdn.net/kesalin/article/details/8798039
- swift-01-利用元组判断字符串出现次数
//问题的提出:有一个字符串 array = ["1","2","4","4","2"," ...
- java新手笔记9 类的封装示例
1.bank类 package com.yfs.javase; //类封装 public class BankCard { //属性 int balance;//默认0 实例变量 分配给每个对象一个 ...
- webui layout like desktop rich client
similarity similarlike desktop js frameworklike extj js frameworklike rich client js frameworkjs lay ...
- ZOJ 2702 Unrhymable Rhymes(DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1702 题目大意:给定有很多数字组成的诗,譬如 “AABB”, “AB ...
- 不对称密钥密码体系之RSA
公钥密码的特性: 1.加密和解密使用不同的钥匙 2.从一个钥匙推出另一个钥匙在计算上不可行 3.每个钥匙都可以做加密和解密 RSA算法: 1978年, MIT三位数学家 R.L.Rivest,A.Sh ...
- 菜鸟的MySQL学习笔记(五)
7.自定义函数 用户自定义函数(user-defined function,UDF)是一种对MySQL扩展的途径,其用法与内置函数相同.包含了两个必要条件,参数与返回值.没有必然内在联系. 函数可以返 ...