String使用时的注意事项:
1)String对象的内容不可改变,被称为不可变字符串对象。
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.
字符串是不变的,他们的值在创建后是无法改变的,字符串缓冲区只是可变字符串,因为字符串对象是不可变的,所以可以共享他们。
一般常量池是在方法区,但是字符串常量池在Java8之后放在堆内存中。
字符串就是一种字符串数组,它的本质是一个数组,所以存的都是地址。
结论:每次试图改变字符串对象实际上是新产生了新的字符串对象了,变量每次都是指向了新的字符串对象,之前字符串对象的内容确实是没有改变的,因此说String的对象是不可变的。
“黑马”、“播妞”、“程序员”这些字符串对象的内容确实都没有改变。
1)直接赋值方式创建:只要是以“...”方式写出的字符串对象,会存储到字符串常量池中,且相同内容的字符串只存一份。
2)通过构造函数创建:但是通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。这个时候虽然内容相同,但是地址不同。
package cn.ensource.string;
public class StringDemo3 {
public static void main(String[] args) {
// 目标:搞清楚String使用时的注意事项
// String类型是不可改变的
String name = "黑马";
name += "程序员";
name += "播妞";
System.out.println(name);
// 直接赋值方式
String str1 = "changchunhua";
String str2 = "changchunhua";
System.out.println(str1 == str2); // true
// 通过构造函数方式创建
char[] chars = {'a', 'b', 'c'};
String a1 = new String(chars);
String a2 = new String(chars);
System.out.println(a1 == a2); // false
}
}
为什么要使用常量池呢?
是为了节省内存。可能量小,我们感觉不到,但是量大的话,效果就非常明显。
阅读程序
这个结果是false。
非常经典的理解程序。
编译器确实帮我们做了编译优化。