public class 常量池_String {
/**字符串一旦被初始化,就不可以被改变
注意: 这里指的是 字符串在常量池里面的值不能发生改变,而不是说字符串的引用不能变*/
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);//helloworld
String s1 = "abc";
//内存中,有一个对象
/**栈内存中,初始化 s1,直接指向方法区的常量池*/
String s2 = new String("abc");
//内存中,有两个对象
/**栈内存中,初始化s2,指向堆内存中的 new String(),最后,由堆内存,指向方法区的常量池*/
//使用常量池的好处: 只要常量池内,已经存在了,就不在产生新的对象
String s3 = "abc";
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
System.out.println(s1.hashCode() == s2.hashCode());//true
System.out.println(s1.equals(s2));//true
/**
* ==比较的是指向的地址是否相同
* String的hashCode 和 equals 比较的是指向的地址 中的内容是否相同
* 仅仅针对 String : 变量名 多对一 指向的地址
*/
String ss1 = "a";
String ss2 = "b";
String ss3 = "ab";
String ss4 = new String("ab");
/**
常量会直接相加, 变量会重新开辟空间
*/
System.out.println(ss3 == ss1 + ss2); //false
System.out.println(ss3 == "a" + "b"); //true
System.out.println(ss3 == ss1 + "b"); //false
System.out.println(ss3 == ss1.concat("b")); //false
System.out.println(ss4 == ss1 + s2); //false
System.out.println(ss4 == "a" + "b"); //false
System.out.println(ss4 == ss1 + "b"); //false
System.out.println(ss4 == ss1.concat("b")); //false
/**
* 常量 与 变量
*
* 如果是变量,系统害怕超出范围
*/
}
}
|