Java String对象创建过程
1. String 类的对象创建
2. String 类的构造方法
——String()
初始化新创建的 String对象,使其表示空字符序列。
例如:
String s = new String();
// s = null;
——String(char[] value)
分配一个新的 String ,以便它表示当前包含在字符数组参数中的字符序列。
例如:
char value[] = {'a','b','c','d'};
String s = new String(value);
// s = "abcd";
—— String(StringBuilder builder)
分配一个新的字符串,其中包含当前包含在字符串构建器参数中的字符序列。
——String(StringBuffer buffer)
分配一个新的字符串,其中包含当前包含在字符串缓冲区参数中的字符序列。
3. String类对象创建过程中的内存分配
字符串的两种实例化方式及其差别
1).String str = “abc”;
2).String str = new String(“abc”);
Java运行时会维护一个String Pool(String池), 也叫“字符串区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
例1:
String name = "张三";
String names = new String("张三");
System.out.println(name == names);
// 输出结果为false;即name 的地址指向与 names的地址指向不一致
如上图所示,name在创建的过程中,地址直接指向字符串常量池的"张三"; names在创建的过程中,在堆中创建一个对象,names的地址指向对象,对象的地址指向字符串常量池的"张三"。
例2:
String s1 = new String("张三");
String s2 = s1;
System.out.println(name == names); //在 Java 中,对于引用类型,
==
运算符比较的是两个变量所指向的对象的引用(也就是内存地址),而不是对象的内容。// 输出结果为true;即name 的地址指向与 names的地址指向一致
- 首先,在字符串常量池中会检查是否有
"张三"
这个字符串常量。如果没有,就会在字符串常量池中创建一个"张三"
的字符串常量对象。 - 然后,
new String()
操作会在堆内存中创建一个新的String
对象,这个对象的内容是指向字符串常量池中的"张三"
字符串(通过字符数组引用等方式)。此时,s1
变量指向的是堆内存中这个新创建的String
对象。 - 接着,
String s2 = s1;
这行代码执行时,s2
变量被赋值为s1
的值。在 Java 中,对象变量存储的是对象的引用(即对象在内存中的地址)。所以s2
现在也指向了堆内存中s1
所指向的那个String
对象。