您的位置:首页 > 编程语言 > Java开发

java常量池理解

2016-02-13 18:48 555 查看

String类两种不同的创建方式

String s1 = "zheng";    //第一种创建方式
String s2 = new String("junxiang");    //第二种创建方式


第一种创建方式是编译期在常量池中创建对象,如果常量池中已经存在"zheng"这个String对象,就将地址赋给s1.第二种创建方式是运行期在堆中创建对象,无论堆中是否已有都会重新创建一个对象。

String s1 = new String("xyz");
String s2 = new String("xyz");


上边创建了3个String对象,编译期常量池创建了1个,运行期堆中创建了2个。

例1:

String s1 = "xyz";
String s2 = "xyz";
System.out.println(s1==s2);
//输出true,因为如果在常量池中已有相同的对象则不再创建而将地址赋给s2。


例2:

String s1 = new String("xyz");
String s2 = new String("xyz");
System.out.println(s1 == s2);
//输出结果是false,因为采用new在堆中每次都会创建一个新对象。


例3:

String x = "zheng";
String y = "jx";
String s = "jxzheng";
String s1 = y + x;
String s2 = "jx" + "zheng";
System.out.println(s1 == s);//输出false,因为字符串连接操作数中有变量。所以运行期才能确定,存在堆中。
System.out.println(s2 == s);//输出true,因为字符串连接操作数都是字符串常量,编译期即可确定,存在常量池中。


总结为以下四条规律:

  1,单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中;

  2,使用new String("")创建的对象会存储到heap中,是运行期新创建的;

  3,使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中;

  4,使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中;

String.intern()

String s1 = new String("xyz");
s1 = s1.intern();//intern()返回在常量池中这个String对象的引用。如果常量池中已经存在这个String对象,则直接返回该对象的引用,否则,在常量池中创建对象并返回引用。


例4:

String s3 = new String("1") + new String("2");
s3.intern();
String s4 = "12";
System.out.println(s3 == s4);//jdk7/8输出结果为true


原因是jdk7中的常量池不是在方法区而是在堆中,可以直接存储对象的引用。所以s4和s3指向的是同一个对象。这篇博客String.intern() Test of JDK6 And JDK7讲解比较清楚。

参考博客:

String之常量池小结

Java堆栈和常量池

Java常量池理解与总结

Java常量池详解之一道面试题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: