Java基础-Java中字符串常量详解

引用自https://www.cnblogs.com/liushengit/p/9298980.html

--------第一个例子---------

String str1 = "a"; 
String str2 = "b"; 
String str3 = "ab"; 
String str4 = str1 + str2;
System.out.println(str3 == str4); //输出结果:false

 为什么会是false呢?

Java中将类似于"Hello"这样的字符串,Jvm在编译期就能确定其值,所以就直接new String("xxx"),并将其存储于常量池中(包括:char、byte、short、int、long、boolean和String类型),所以上面的str1、str2、str3 指向的均是常量池中对象;

而String str4 = str1 + str2就不同了,+号两边(或任意一边)是变量,Jvm在编译期是无法确定其值的,要等到运行期再进行处理,处理方法为:先用str1在堆内存中new一个StringBuilder,然后append(str2),然后调用toString()将其引用赋值给str4,所上面的str4指向的是堆内存的一个字符串对象,如下图所示:

--------第二个例子--------- 

复制代码
String str1 = "a"; 
String str2 = "b"; 
String str3 = "ab"; 
String str4 = str1 + str2;
String str5 = str4.intern();
System.out.println(str3 == str5); //输出结果:true
复制代码

 这里又为什么会是true呢?

String的intern()方法会将该对象的值转到常量池中去,如果字符串池已有同样的值,则直接返回地址,如果没有,则在字符串池中新建一个,然后返回地址。
再看此例子,显然"ab"已经在常量池中存在了(str3 = "ab"),所以str5和str3均指向常量池中的"ab",且语法str3 == str5比较是引用地址,所以输出结输出结果为:true;
注:intern()这个方法API里的解释是:“当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串 (用equals(Object) 方法判断),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。”

 

--------第三个例子---------

String str1 = "ab"; 
String str2 = "a" + "b"; 
System.out.println(str1 == str2); //输出结果:true

 这里又为什么会是true呢?

第一行:"ab"作为一个常量存放于字符串池中,并把引用地址赋值给str1;
第二行:"a"和"b"作为两个常量相加,由于编译器优化,在编译期就将+两边拼接合并了,直接认为成是一个常量"ab",结果发现字符串池中已经有一个常量"ab"了,就直接把"ab"的引用地址赋值给了str2;
第三行:str1 == str2比较的str1和str2的引用地址,当然是一样的,so输出结果: true ;

 

--------第四个例子---------

final String str1 = "a";
final String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
System.out.println(str3 == str4);//输出结果:true

 

这里又为什么会是true呢?
第一行:"a"作为一个常量存放于字符串池中,并将它的引用地址赋值给了str1; final使得变量str1被当作一个常量对待
第二行:"b"作为一个常量存放于字符串池中,并将它的引用地址赋值给了str2; final使得变量str2被当作一个常量对待
第三行:"ab"作为一个常量存放于字符串池中,并将它的引用地址赋值给了str3;
第四行:str1 + str2,此时+号两边都是常量哦(final的功劳)
               即:String str4 = str1 + str2; 
               就等价于 String str4 = "a" + "b";
               就等价于 String str4 = "ab";
第五行:str4指向常量"ab",str3指向常量"ab"(第三行),所以str3 == str4 等于true

posted @ 2023-08-22 14:25  江境纣州  阅读(140)  评论(0编辑  收藏  举报