簡述String類型


要了解String類型的特性,首先了解java的基礎知識。

一、 基本數據類型和引用數據類型

JVM中使用棧來存儲方法以及非全局的變量,對於基本類型來說,棧中既存變量又存值,基本類型有8種:boolean, byte,short,int, long,float, double, char, 不是基本類型的類型稱為引用類型,對於引用類型來說,棧中存變量及對象內存地址,對象內存地址指向實際對象實例。String 就是引用數據類型。基本數據類型之間的比較使用"==", 引用類型比較通常有特定的方法如equals方法。

二、 字符串常量池

String 作為引用類型,正常來說創建應該是String str = new String("Hello");,但是String太常用,幾乎每一個類型都包含這個類型的對象,這樣創建String對象就會帶來大量的時間和空間開銷,影響程序的性能,所以JVM對String類型的創建做了優化,設計了字符串常量池替代new創建String類型,變成了String str = "Hello";String類型在創建時首先會去字符串常量池中查找是否存在該字符串,如果沒有則創建改字符串,如果有,則將引用指向該字符串。這樣設計多個變量就會指向同一個字符串對象,一個變量修改就會影響另外的引用,為了消除這種影響,String類型被設計為final修飾。字符串常量池存在JVM方法區,所以里面的字符串不會被輕易回收。

三、 方法參數的值傳遞和引用傳遞

在java中,方法參數的值傳遞和引用傳遞對應基本數據類型和引用數據類型,基本數據類型參數是值傳遞,引用數據類型是參數傳遞。值傳遞的特點是方法傳參數時,會將原變量(基本數據類型變量和值存一起)拷貝一個副本傳入方法,方法中對拷貝的副本操作並不會影響原變量。引用傳遞也會將原變量拷貝一個副本傳入方法,但是由於變量存的是引用地址,所以方法中對變量的修改會影響原變量。String是引用數據類型,也就有引用傳遞的特點,但是java中String是fina修飾的,也就是不可變的,傳入方法也不會被修改。

四、 String的創建

    public static void main(String[] args) {
        String str = "Hello";
        String str2 = "Hello";

        String str3 = new String("Hello");
        String str4 = new String("Hello");

        String str5 = str;

        System.out.println("str == str2:" + (str == str2));
        System.out.println("str == str3:" + (str == str3));
        System.out.println("str3 == str4:" + (str3 == str4));
        System.out.println("str2 == str5:" + (str2 == str5));
        System.out.println("str equals str3:" + (str.equals(str3)));
    }
  • String str = "Hello" 在創建時會在字符創常量池創建字符串對象 "Hello",
  • String str2 = "Hello" 在創建時會在字符創常量池查找"Hello", 發現已存在,會指向"Hello", str == str2為true。
  • str3 和 str4 在創建時都會在堆中new一個新對象實例,所以str == str3 和 str3 == str4 都是false
  • String str5 = str中,str5也是指向常量池字符串, 所以 str2 == str5 為true
  • String重寫了equals方法,比較是兩個String對象的值,所以str.equals(str3)為true

執行結果:

str == str2:true
str == str3:false
str3 == str4:false
str2 == str5:true
str equals str3:true

圖解String的創建:

5. String類型的參數傳遞

    public static void main(String[] args) {
        int ii = 10;
        Map<String, String> map = new HashMap<>();
        map.put("key", "Hello");
        String str = "Hello";
        String str2 = new String("Hello");
        change1(ii);
        System.out.println("ii: " + ii);
        change2(map);
        System.out.println("map: " + JSON.toJSONString(map));
        change3(str);
        System.out.println("str: " + str);
        change4(str2);
        System.out.println("str2: " + str2);

    }
    public static void change1(int ii) {
        ii = 50;
    }
    public static void change2(Map<String, String> map) {
        map.put("key", "world");
    }
    public static void change3(String str) {
        str = "你好!";
    }
    public static void change4(String str2) {
        str2 = new String("你好!");
    }
  • ii變量是基本數據類型int,chang1方法執行是拷貝了ii的副本並修改並不能改變ii的值。
  • map變量是引用數據類型,chang2方法中操作的map和原map變量都指向同一個HashMap對象,所以chang2方法對map的修改會影響到原map
  • str和str2都是引用數據類型,但是String不可被修改,所以str = "你好!" 和 str2 = new String("你好!") 都是創建一個新的對象,所以不會影響到原變量。

執行結果:

ii: 10
map: {"key":"world"}
str: Hello
str2: Hello

圖解執行change方法前后如下圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM