String類的使用2

小白衝發表於2021-04-14
/*
String:字串,使用一對""引起來表示。
1.String宣告為final的,不可被繼承
2.String實現了Serializable介面:表示字串是支援序列化的。
實現了Comparable介面:表示String可以比較大小
3.String內部定義了final char[] value用於儲存字串資料
4.String:代表不可變的字元序列。簡稱:不可變性。
體現:1.當對字串重新賦值時,需要重寫指定記憶體區域賦值,不能使用原有的value進行賦值。
2. 當對現有的字串進行連線操作時,也需要重新指定記憶體區域賦值,不能使用原有的value進行賦值。
3. 當呼叫String的replace()方法修改指定字元或字串時,也需要重新指定記憶體區域賦值,不能使用原有的value進行賦值。
5.通過字面量的方式(區別於new)給一個字串賦值,此時的字串值宣告在字串常量池中。
6.字串常量池中是不會儲存相同內容的字串的。
*/
 @Test
    public void test1(){
        String s1 = "abc";//字面量的定義方式
        String s2 = "abc";
        s1 = "hello";

        System.out.println(s1 == s2);//比較s1和s2的地址值

        System.out.println(s1);//hello
        System.out.println(s2);//abc

        System.out.println("*****************");

        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println(s2);

        System.out.println("*****************");

        String s4 = "abc";
        String s5 = s4.replace('a', 'm');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc

    }

 

 


/*
String的例項化方式:
方式一:通過字面量定義的方式
方式二:通過new + 構造器的方式

面試題:String s = new String("abc");方式建立物件,在記憶體中建立了幾個物件?
兩個:一個是堆空間中new結構,另一個是char[]對應的常量池中的資料:"abc"

*/

@Test
    public void test2(){
        //通過字面量定義的方式:此時的s1和s2的資料javaEE宣告在方法區中的字串常量池中。
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通過new + 構造器的方式:此時的s3和s4儲存的地址值,是資料在堆空間中開闢空間以後對應的地址值。
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");

        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s1 == s4);//false
        System.out.println(s3 == s4);//false

        System.out.println("***********************");
        Person p1 = new Person("Tom",12);
        Person p2 = new Person("Tom",12);

        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true

        p1.name = "Jerry";
        System.out.println(p2.name);//Tom
    }

 

 


/*
String 與 byte[]之間的轉換
編碼:String --> byte[]:呼叫String的getBytes()
解碼:byte[] --> String:呼叫String的構造器

編碼:字串 -->位元組 (看得懂 --->看不懂的二進位制資料)
解碼:編碼的逆過程,位元組 --> 字串 (看不懂的二進位制資料 ---> 看得懂)

說明:解碼時,要求解碼使用的字符集必須與編碼時使用的字符集一致,否則會出現亂碼。
*/

@Test
    public void test3() throws UnsupportedEncodingException {
        String str1 = "abc123中國";
        byte[] bytes = str1.getBytes();//使用預設的字符集,進行編碼。
        System.out.println(Arrays.toString(bytes));

        byte[] gbks = str1.getBytes("gbk");//使用gbk字符集進行編碼。
        System.out.println(Arrays.toString(gbks));

        System.out.println("******************");

        String str2 = new String(bytes);//使用預設的字符集,進行解碼。
        System.out.println(str2);

        String str3 = new String(gbks);
        System.out.println(str3);//出現亂碼。原因:編碼集和解碼集不一致!


        String str4 = new String(gbks, "gbk");
        System.out.println(str4);//沒有出現亂碼。原因:編碼集和解碼集一致!


    }

 

 

 
/*
結論:
1.常量與常量的拼接結果在常量池。且常量池中不會存在相同內容的常量。
2.只要其中有一個是變數,結果就在堆中。
3.如果拼接的結果呼叫intern()方法,返回值就在常量池中
*/
@Test
    public void test4(){
        String s1 = "javaEEhadoop";
        String s2 = "javaEE";
        String s3 = s2 + "hadoop";
        System.out.println(s1 == s3);//false

        final String s4 = "javaEE";//s4:常量
        String s5 = s4 + "hadoop";
        System.out.println(s1 == s5);//true

    }

    @Test
    public void test3(){
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false

        String s8 = s6.intern();//返回值得到的s8使用的常量值中已經存在的“javaEEhadoop”
        System.out.println(s3 == s8);//true


    }

 

相關文章