永不退缩 永不退缩

I,can do

目录
重新出发000002-阅读文章"Java字符串那些事儿"。
/        

重新出发000002-阅读文章"Java字符串那些事儿"。

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));
    }

}