String str1="hello"; // 存放在字符串常量池中 String str2="he"+new String("llo"); // 存放在堆内存中 System.out.println(str1==str2);//false
java.lang.String.intern(),这个API可以手动将一个字符串对象的值转移到字符串常量池中 在1.7及之前,字符串常量池是在永久代(方法区),大小是固定的,也不能被垃圾回收器回收,如果有太多了字符换调用了intern方法的话,就有可能造成OOM。 1.8里,字符串常量池移到了堆内存中,可以被垃圾回收器回收降低了字符串常量池OOM的风险。 补充:
1、两个或者以上的字符串常量相加,【String str="s1"+"s2"】,在预编译的时候“+”会被优化,相当于把两个或者两个以上字符串常量自动合成一个字符串常量
2、字符串的+操作本质上是new了StringBuilder对象进行append操作,拼接后调用toString()返回String对象(可通过javap -c xxx.class查看字节码指令)
Code: 0: ldc #10 // String hello 2: astore_1 3: new #11 // class java/lang/StringBuilder 6: dup 7: invokespecial #12 // Method java/lang/StringBuilder."<init>":()V 10: ldc #13 // String he 12: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: new #15 // class java/lang/String 18: dup 19: ldc #16 // String llo 21: invokespecial #17 // Method java/lang/String."<init>":(Ljava/lang/String;)V 24: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 27: invokevirtual #18 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
END.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。