尝试回答下面的问题
package com.example.demo;
import javax.print.attribute.standard.RequestingUserName;
/**
* @author micro.cloud.fly
* @date 2022/10/12 10:40 AM
* @desc
*/
public class Stringtest03 {
public static void main(String[] args) {
String s1 = new String( "a");
String s2 = new String( "b");
String s3 = s1+s2;
System.out.println(s3 == "ab");
String k= "ab";
String k1 = new String( "a");
String k2 = new String( "b");
String k3 = s1+s2;
System.out.println(k3==k);
String m= "ab";
String m1 = new String( "a");
String m2 = new String( "b");
String m3 = m1+m2;
String m4=m3.intern();
System.out.println(m==m4);
System.out.println(m3==m4);
String h1 = new String( "m");
String h2 = new String( "n");
String h3 = h1+h2;
String h4=h3.intern();
System.out.println("---------");
System.out.println(h4=="mn");
System.out.println(h4==h3);
}
}
分析1
String s1 = new String( "a");//s1为被new出来的对象,所以s1放入了堆中,但是"a"是字符串常量,会被放入字符串常量池中。
String s2 = new String( "b");//同上,s2在堆中,"b"在常量池中
String s3 = s1+s2;//底层调用了stringbuilder,也是被new出来的对象,s3放入了堆中,虽然s3的值为“ab”,但是s3是动态生成的字符串,不会被放入到常量池中
System.out.println(s3 == "ab");//"ab"为字符串常量,所以会被放入到常量池中,是属于常量池中的字符串对象,所以s3==“ab”为false;
分析2
String k= "ab";
String k1 = new String( "a");
String k2 = new String( "b");
String k3 = s1+s2;
System.out.println(k3==k);
答案是false,因为k3在堆中,而k是字符串常量池stringTable中的对象
分析3
String m= "ab";
String m1 = new String( "a");
String m2 = new String( "b");
String m3 = m1+m2;
String m4=m3.intern();
System.out.println(m==m4);
System.out.println(m3==m4);
此处m4=m3.intern(),m3的值为“ab”,m3尝试把“ab”放入到常量池中,但是常量池中已经有了,所以没有放入成功,所以m3还是对中的对象,但是依然会把常量池中的“ab”字符串对象返回,也就是m4,所以m==m4为true,此时m3依然是存在于堆中,所以m3 == m4为false。
分析4
String h1 = new String( "m");
String h2 = new String( "n");
String h3 = h1+h2;
String h4=h3.intern();
System.out.println("---------");
System.out.println(h4=="mn");
System.out.println(h4==h3);
String h4=h3.intern();这行,h3尝试把字符串对象放入到字符串常量池中时,发现没有,于是放入成功,所以h3也指向了常量池中的字符串对象,同时返回的h4也是常量池中的字符串对象,所以,这里的结果都为true。
可以参考:
https://blog.youkuaiyun.com/Lucky_Boy_Luck/article/details/106587260