String 与 intern理解
2016-05-07 14:53
411 查看
1.
public static void main(String[] args) { String s = new String("abc"); System.out.println(s == s.intern()); }
在这个代码中,首先创建的String对象是“abc”这个string字面量,然后才是new String 这个对象,为什么?因为在编译期,“abc”就已经存在.class中的常量池中,当类加载的时候,把它从.class中加载进来,在堆中首先创建了这个“abc”字面量的对象。当所有的类加载工作完成后才去执行代码指令。关于运行时常量池中的string,保存的是这个string对象的引用,而什么决定了它应该保存哪个对象的引用呢,像上面的代码,它保存的是s这个引用还是“abc”对象的引用呢?谁先创建出对象谁的引用就会放置在常量池中,所以常量池的引用就是“abc”对象的引用。
intern方法:调用这个方法的String对象的字面量在常量池中已经存在引用,就返回常量池的引用,否则就将这个对象的引用作为这个字面量的引用。上面的例子就是:s调用intern方法,JVM就去常量池看看是否有“abc”这个字面量的引用,有就返回这个引用,也就是“abc”这个对象的引用,所以上面的打印结果就是false;
2.
public static void main(String[] args) { String s = new StringBuilder("game ").append("over").toString(); System.out.println(s == s.intern()); }
2.这个例子中s的字面量为“game over”,而在常量池中只有“game ”和“over” 两个字面量的引用,所以当s调用intern方法的时候,JVM发现常量池没有“game over”字面量引用,所以将“game over”解释为s这个引用,所以打印结果为true
3.
public static void main(String[] args) { String str = "game over"; String s = new StringBuilder("game ").append("over").toString(); System.out.println(s == s.intern()); System.out.println(str == s.intern()); }
3.这个例子中在2.的例子最前面加了
String str = "game over";
那么当s调用intern返回的就是str这个引用,所以打印就是 false ,true
4.
public static void main(String[] args) { String s = new StringBuilder("game over").toString(); System.out.println(s == s.intern()); }
而4.这个例子1.这个例子是一样的,s调用返回的是“game over”这个对象的引用,当然是不等于s,所以打印结果为false
5.
public static void main(String[] args) { String s = new StringBuilder("jav").append("a").toString(); System.out.println(s == s.intern()); }
那么5.这个例子的结果又是什么?
结果是false,因为在
new StringBuilder("jav").append("a").toString();
这句代码执行之前,在常量池中已经长在“java”这个字面量对象的引用了,stackoverflow有这个问题的讨论,
At a guess, this class is used on startup to launch the programdocjar.com/html/api/com/sun/tools/jdi/… and
on line 125 there is the String literal
"java"– Peter
Lawrey,程序运行时“java”字面量对象的引用就存在常量区,
6
public static void main(String[] args) { String s = new StringBuilder("ja").append("va").toString(); System.out.println(s.intern() == "java"); }
6这个例子是true ,Java语言说明中要求字符串字面量必须唯一,一样的字符串字面量必须为同一个String实例。所以“java“与intern返回的引用是同一个引用
7
public static void main(String[] args) { String s = "abc"; String s1 = "abc"; String s2 = "abc"; System.out.println(s == s1); System.out.println(s == s2); System.out.println(s.intern() == s); System.out.println(s1.intern() == s); System.out.println(s2.intern() == s); }
打印的结果都是true,在常量区中存在的引用一直是”abc“,在堆中只创建了一个String对象(引用忽略)
8.
public static void main(String[] args) { String s = "ab"; String s1 = "a" + "b"; System.out.println(s == s1);//true String s2 = "c" + "d"; String s3 = new StringBuilder("c").append("d").toString(); System.out.println(s3 == s3.intern());//false System.out.println(s2 == s3.intern());//true String s4 = "efg" + "h"; String s5 = new StringBuilder("eg").append("f").toString(); System.out.println(s5.intern() == s5);//true }
java对”+“连接为优化后的值,javap查看
String s4 = "efg" + "h"; String s5 = new StringBuilder("eg").append("f").toString(); System.out.println(s5.intern() == s5);//true
这段代码则证明了,”efg“在s5调用intern之前在常量池不存在它的引用,所以
s5.intern() == s5);为true
9.
public static void main(String[] args) { String s = "a"; String s1 = s + "b"; String s2 = "ab"; System.out.println(s1 ==s2); final String s3 = "c"; String s4 = s3 + "d"; String s5 = "cd"; System.out.println(s4 == s5); }
JVM只能优化常量值,对于引用,只有到真正运行到那一步的时候才能确定它的值,所以打印结果为false,true
然后再这样
public static void main(String[] args) { String s = "a"; String s1 = s + "b"; // String s2 = "ab"; // System.out.println(s1 ==s2); final String s3 = "c"; String s4 = s3 + "d"; String s5 = "cd"; System.out.println(s4 == s5); }
查看.class文件
并不存在String ”ab“这两个值
今天累死
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/bye.gif)
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager