// String 类
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
....
}
1、value[] 数组是 final 类型,表示 value 的引用地址不可变,但是 Arrary 数组是可变的
final char[] charArray = {'a', 'b', 'c', 'd', 'e'};
char ch = 'z';
charArray[0] = ch;
System.out.println(charArray);
2、但是由于 value[] 数组私有,且没有提供外部访问能力,因此无法修改
// 继承 AbstractStringBuilder 实现不同
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
// 在常量池中
String str1 = "abc";
// 在堆上
String str2 = new String("abc");
// 字符串常量 + 号的重载 编译时合并成 abcdef 字符串
String str3 = "abc" + "def";
String str4 = "abc" + new String("def");
String str41 = new String("def") + "abc";
String str5 = new String("abc") + new String("def");
String str6 = "defabc";
String str1 = "abc";
String str2 = "abc";
// 直接在字符串常量池中查找,如果存在直接使用,不存在创建,即str1、str2指向常量池中的同一个值
String str2 = new String("abc");
// 在堆中创建一个 String 对象,判断 abc 在字符串常量是否存在,存在char数组直接指向,不存在创建新的字符串常量再指向
// 上述检查常量池是否有相同Unicode的字符串常量时,使用的方法是String中的intern()方法
// 字符串常量 + 号的重载 编译时优化合并成 abcdef 字符串
String str3 = "abc" + "def";
String str4 = "abc" + new String("def");
String str41 = new String("def") + "abc";
String str5 = new String("abc") + new String("def");
// 上面三种情况,都会先创建一个 StringBuilder 对象再进行字符串拼接,最后调用toString()方法创建一个 String 对象
// 注意: 在这里创建 String 时,并没有在字符串常量池中创建,而是直接指向了 StringBuilder 的 value 数组
// @Override
// public String toString() {
// Create a copy, don't share the array
// return new String(value, 0, count);
// }
String str6 = "defabc";
// 因此,上述 String str6 = "defabc" 会在字符串常量池中创建 "defabc" 常量
public class MainTest {
public static void main(String[] args) throws InterruptedException {
// 在常量池中
String str1 = "abc";
// 在堆上
String str2 = new String("abc");
// 字符串常量 + 号的重载 编译时合并成 abcdef 字符串
String str3 = "abc" + "def";
String str4 = "abc" + new String("def");
String str41 = new String("def") + "abc";
String str5 = new String("abc") + new String("def");
String str6 = "defabc";
}
}
// javap -c .\MainTest.class
Compiled from "MainTest.java"
public class org.example.MainTest {
public org.example.MainTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
Code:
---------------------------------------------String str1 = "abc"; --------------------------------------------------------------------------
0: ldc #2 // String abc
2: astore_1
---------------------------------------------String str2 = new String("abc");---------------------------------------------------------------
3: new #3 // class java/lang/String // 创建 String 对象
6: dup
7: ldc #2 // String abc
9: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
12: astore_2
---------------------------------------------String str3 = "abc" + "def";-------------------------------------------------------------------
13: ldc #5 // String abcdef 编译时优化为 "abcdef"
15: astore_3
---------------------------------------------String str4 = "abc" + new String("def");-------------------------------------------------------
16: new #6 // class java/lang/StringBuilder // 创建 StringBuilder
19: dup
20: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
23: ldc #2 // String abc
25: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; //拼接 abc
28: new #3 // class java/lang/String 创建 String 对象(def)
31: dup
32: ldc #9 // String def
34: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
37: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; //拼接 def
40: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; // 调用 toString 方法生成一个新 String 对象
43: astore 4
--------------------------------------------------------------------------------------------------------------------------------------------
45: new #6 // class java/lang/StringBuilder
48: dup
49: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
52: new #3 // class java/lang/String
55: dup
56: ldc #9 // String def
58: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
61: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
64: ldc #2 // String abc
66: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
69: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
72: astore 5
74: new #6 // class java/lang/StringBuilder
77: dup
78: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
81: new #3 // class java/lang/String
84: dup
85: ldc #2 // String abc
87: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
90: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
93: new #3 // class java/lang/String
96: dup
97: ldc #9 // String def
99: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
102: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
105: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
108: astore 6
110: ldc #11 // String defabc
112: astore 7
114: return
}
案例一:
String str3 = "abc" + "def";
编译阶段优化为 “abcdef” 在常量池创建一个对象 “abcdef”
案例二:
String str4 = "abc" + new String("def")
"abc" 在常量池创建一个对象
new String("def") 在堆中创建一个 String 对象,常量池创建对象 "def"
创建一个 StringBuilder 对象用于拼接两个字符串,最后调用 toString() 方法创建一个 String 对象
// 即在不考虑字符串常量池已存在常量字符串的情况,需要创建 5 个对象
// 再思考一下:其实还有一个强引用对象 str4 对创建字符串的强引用
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。
🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。
💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。
🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。
📖 保持关注我的博客,让我们共同追求技术卓越。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。