package review.base.Java那些事儿;
public class 二_Java字符串那些事儿 {
public static void main(String[] args) {
TestString ts = new TestString();
ts.testString();
System.out.println("看两个特例:");
ts.testFinalString();
ts.testStaticString();
System.out.println("看String.itern()方法:");
ts.testStringItern();
}
}
class TestString {
public static final String A = "ab";
public static final String B = "cd";
public static final String C;
public static final String D;
static {
C = "ab";
D = "cd";
}
public void testString() {
String s1 = "100";
String s2 = "100";
System.out.println("String:" + (s1 == s2));
String s3 = new String("100");
String s4 = new String("100");
System.out.println("String:" + (s3 == s4));
/**
* 参考文章来自:
* https://zhuanlan.zhihu.com/p/27570687 java字符串
* https://www.jianshu.com/p/c7f47de2ee80 java常量池
*
* 通过输出可以看到,结果是:
* true
* false
*
* 不是字符串比较不能用==么。难道又是valueOf么。
* 通过反编译,我们可以看到代码会被编译成:
* String s1 = "100";
* String s2 = "100";
* System.out.println("String:" + (s1 == s2));
* String s3 = new String("100");
* String s4 = new String("100");
* System.out.println("String:" + (s3 == s4));
* 其实没有变.....
*
* 这里其实是常量池的锅。
*
* 在JVM中,当代码执行到String s1 = "100" 时,会先看常量池里有没有字符串刚好是“100”这个对象,如果没有,在常量池里创建初始化该对象,并把引用指向它。
*
* 而使用了new,就相当于告诉JVM,给我一个新的空间,老子是独一无二的。
*
*
*/
// 举几个其他例子 String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
System.out.println(str3 == str4); // 由于str4是两个变量相加,无法创建在常量池中。所以无法同str3放在同一个内存位置中。
String str5 = "string";
System.out.println(str3 == str5); // 由于str3是两个字面量相加,其产生的结果会直接被放在常量池中。
}
public void testFinalString() {
// 由于是两个常量相加,所以等同于字面量"ab"+"cd"
String s = A + B;
String s2 = "abcd";
System.out.println(s == s2);
}
public void testStaticString() {
// 虽然是常量,但是由于编译的时候还不确定值,所以还是认为是变量。
String s = C + D;
String s2 = "abcd";
System.out.println(s == s2);
}
/**
* Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。 * 通过例子看一下:
*/ public void testStringItern(){
String s1 = new String("计算机");
String s2 = s1.intern();
String s3 = "计算机";
System.out.println("s1 == s2? " + (s1 == s2));
System.out.println("s3 == s2? " + (s3 == s2));
}
}