一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

java中String類型變量的賦值問題

 看風景D人 2016-10-22

第一節(jié) String類型的方法參數(shù)

運行下面這段代碼,其結果是什么?

復制代碼
package com.test;

public class Example {
    
    String str = new String("good");
    char[] ch = { 'a', 'b', 'c' };

    public static void main(String[] args) {
        Example ex = new Example();
        ex.change(ex.str, ex.ch);
        System.out.println(ex.str);
        System.out.println(ex.ch);
    }

    public void change(String str, char ch[]) {
        str = "test ok";
        ch[0] = 'g';
    }
    
}
復制代碼

結果如下:

good
gbc

解說:java 中String是 immutable的,也就是不可變,一旦初始化,引用指向的內容是不可變的(注意:是內容不可變)。

  也就是說,假設代碼中有String str = “aa”;str=“bb”;,則第二條語句不是改變“aa”原來所在存儲地址中的內容,而是另外開辟了一個空間用來存儲“bb”;同時由于str原來指向的“aa”現(xiàn)在已經不可達,jvm會通過GC自動回收。
  在方法調用時,String類型和數(shù)組屬于引用傳遞,在上述代碼中,str作為參數(shù)傳進change(String str, char ch[]) 方法,方法參數(shù)str指向了類中str指向的字符串,但str= "test ok"; 語句使得方法參數(shù)str指向了新分配的地址,該地址存儲“test ok”,而原來的str仍然指向“good”。對于數(shù)組而言,在change方法中,方法參數(shù)ch指向了類中ch指向的數(shù)組,ch[0] = 'g';語句改變了類中ch指向的數(shù)組的內容

 

我們再來看下面這段代碼,它的運行結果是什么?

復制代碼
package com.test;

public class Example {
    
    String str = new String("good");
    char[] ch = { 'a', 'b', 'c' };

    public static void main(String[] args) {
        Example ex = new Example();
        ex.change(ex.str, ex.ch);
        System.out.println(ex.str);
        System.out.println(ex.ch);
    }

    public void change(String str, char ch[]) {
        str = str.toUpperCase();
        ch = new char[]{ 'm', 'n' };
    }
    
}
復制代碼

結果如下:

good
abc

結合前面的解釋進行理解,這個結果是不是在意料之中?!

 

根據JDK中java.lang.String的源碼進行分析,從中可以得出String類型的對象不可變的原因,大致上有如下兩個:

  1、java.lang.String類型在實現(xiàn)時,其內部成員變量全部使用final來修飾,保證成員變量的引用值只能通過構造函數(shù)來修改;

  2、java.lang.String類型在實現(xiàn)時,在外部可能修改其內部存儲值的函數(shù)實現(xiàn)中,返回時一律構造新的String對象或者新的byte數(shù)組或者char數(shù)組;

僅憑第1點還不能保證其不可變特性:假如通過String類型的toCharArray方法可以直接訪問String類型內部定義的char數(shù)組,那么即便String類型內部的char數(shù)組使用了final來修飾,也僅僅保證這個成員變量的引用不可變,而無法保證引用指向的內存區(qū)域不可變。

第2點保證了外部不可能修改java.lang.String類型對象的內部屬性,從而保證String對象是不可變的。


 

第二節(jié) String類型變量的賦值

2.1 String變量賦值方式:s2=new String(s1)

下面這段代碼的運行結果是什么

復制代碼
package com.soft;

public class ExecutorsDemo {
    
    public static void main(String[] args) {
        String s1="abc"+"def";
        String s2=new String(s1);
        if(s1.equals(s2))
            System.out.println("equals succeeded");
        if(s1==s2)
            System.out.println("==succeeded");
    }
}
復制代碼

結果:

equals succeeded

解說:上述代碼中,s1與s2指向不同的對象,但是兩個對象的內容卻是一樣的,故“s1==s2”為假,s1.equals(s2)為真。

此處我們來細說一下"=="與equals的作用:

 ?。?)"=="操作符的作用

    A、用于基本數(shù)據類型的比較

    B、判斷引用是否指向堆內存的同一塊地址

 ?。?)equals的作用

    用于判斷兩個變量是否是對同一個對象的引用,即堆中的內容是否相同,返回值為布爾類型

 

2.2 String變量賦值方式:s2 = s1

復制代碼
package com.soft;

public class ExecutorsDemo {
    
    public static void main(String[] args) {
        String s1 = new String("java");
        String s2 = s1;

        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
    }
}
復制代碼

 結果:

true
true

解說:如果理解了前面那個例子的運行情況,那么這個就是一目了然的事情,此處s1與s2指向同一個對象,"=="操作符的作用之一就是判斷引用是否指向堆內存的同一塊地址,equals的作用是判斷兩個變量是否是對同一個對象的引用(即堆中的內容是否相同),故此處均輸出“true”


 

第三節(jié) 將字符數(shù)組或字符串數(shù)組轉換為字符串

此處再補充兩個應用場景

一、將字符數(shù)組轉換為字符串

下面代碼中的兩種方式均可直接將字符數(shù)組轉換為字符串,不需要遍歷拼接

復制代碼
package com.test;

public class Main {
    
    public Main() {
    }

    public static void main(String[] args) {
        char[] data = {'a', 'b', 'c'};
//      String str = new String(data);
        String str = String.valueOf(data);
        System.out.println(str);
    }
    
}
復制代碼

此處可以看一下其他作者的文章以深入理解:【Java】數(shù)組不能通過toString方法轉為字符串  http://www.cnblogs.com/ningvsban/p/3955483.html

 

二、將字符串數(shù)組轉換為字符串

下面的代碼是我們常用的方式,循環(huán)拼接

復制代碼
package com.test;

public class Main {
    
    public Main() {
    }

    public static void main(String[] args) {
        String[] ary = {"abc", "123", "45"};
        String s = "";
        for(String temp : ary) {
            s=s.concat(temp);//和下面的一行二選一即可
//          s += temp;
        }
        System.out.println(s);
    }
    
}
復制代碼

上述代碼段不需要過多解釋了


 

 

第四節(jié) StringBuffer和StringBuilder

提到String,就不得不提一下JDK中另外兩個常用來表示字符串的類,StringBuffer和StringBuilder。在編寫java代碼的過程中有時要頻繁地對字符串進行拼接,如果直接用“+”拼接的話會建立很多的String型對象,嚴重的話會對服務器資源和性能造成不小的影響;而使用StringBuilder和StringBuffer能解決以上問題。根據注釋,StringBuffer可謂老資格了,從JDK1.0時即伴隨Java征戰(zhàn)世界,而StringBuilder直到JDK1.5時才出現(xiàn)。面試時,StringBuffer和StringBuilder的區(qū)別也是常問的話題,StringBuffer是線程安全的,而StringBuilder不是線程安全的。

一、StringBuffer和StringBuilder的共同點:

1、用來完成字符串拼接操作;

2、都是可變對象,對象內的字符緩存會隨著拼接操作而動態(tài)擴展;

3、構造時傳入內部緩存大小時,可以降低緩存擴展的次數(shù),明顯提升字符串拼接操作的效率;

二、StringBuffer和StringBuilder的區(qū)別:

1、StringBuilder的方法都是線程不安全的,從另外一個角度講,StringBuilder類型的對象在做字符串拼接操作時,由于少了線程同步的操作,執(zhí)行效率上有很大提升;

2、StringBuffer的方法都加上了synchronized關鍵字,因而在一定的場景下,StringBuffer類型的對象都是線程安全的,但在執(zhí)行效率上,由于多了線程同步的操作,因而會有少許的損失;

在大多數(shù)場景下,字符串拼接操作都是不需要考慮多線程環(huán)境下對結果的影響的,因而使用StringBuilder類型可以提升代碼的執(zhí)行效率。

在多個線程的代碼中共享同一個StringBuffer類型的對象時,需要關注synchronized關鍵字對最終結果的影響。由于StringBuffer類的實現(xiàn)中,僅僅對每個方法使用了synchronized修飾,這只能保證在多線程場景下,訪問StringBuffer對象的同一個方法時可以保證最終結果的一致性,假如一個線程訪問A方法,另外一個線程方法B方法,則由于加鎖對象的不同,可能會出現(xiàn)不一致的現(xiàn)象,這是需要程序員特別要注意的地方。類似的,可以參考Vector的實現(xiàn)和應用場景。

 

針對上面的將字符串數(shù)組轉換為字符串,可以借助上面提到的StringBuilder(當然StringBuffer也可以),代碼如下:

復制代碼
package com.test;

public class Main {
    
    public Main() {
    }

    public static void main(String[] args) {
        String[] ary = {"abc", "123", "45"};
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < ary.length; i++){
            sb. append(ary[i]);
        }
        String newStr = sb.toString();
        System.out.println(newStr);
    }
    
}
復制代碼

 

參考資料

這里有兩篇文章,值得一讀:

(1)三分鐘理解Java中字符串(String)的存儲和賦值原理 http://blog.csdn.net/zhuiwenwen/article/details/12351565

(2)Java之內存分析和String對象 http://www.cnblogs.com/devinzhang/archive/2012/01/25/2329463.html

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    久久永久免费一区二区| 免费黄色一区二区三区| 91人妻人澡人人爽人人精品| 欧美国产日韩在线综合| 欧美精品久久99九九| 国内自拍偷拍福利视频| 熟女中文字幕一区二区三区| 国产在线一区二区三区不卡| 极品少妇嫩草视频在线观看| 日本加勒比系列在线播放| 午夜精品久久久免费视频| 国产在线观看不卡一区二区| 中文字幕久久精品亚洲乱码| 人妻亚洲一区二区三区| 欧美一级黄片欧美精品| 日本一区二区三区黄色| 国产大屁股喷水在线观看视频| 丰满人妻熟妇乱又伦精另类视频| 精品国产亚洲一区二区三区| 老鸭窝老鸭窝一区二区| 国产综合一区二区三区av | 亚洲第一区二区三区女厕偷拍| 欧美成人黄色一区二区三区| 五月婷婷欧美中文字幕| 欧美一级片日韩一级片| 激情内射日本一区二区三区| 亚洲一级在线免费观看| 太香蕉久久国产精品视频| 日韩精品一区二区一牛| 欧美日韩视频中文字幕| 国产精品一区二区高潮| 日本精品中文字幕在线视频| 91蜜臀精品一区二区三区| 麻豆视传媒短视频在线看| 国产农村妇女成人精品| 好吊妞视频免费在线观看| 日韩国产欧美中文字幕| 五月婷婷缴情七月丁香 | 久热在线视频这里只有精品| 国产精品白丝久久av| 日韩一区二区三区18|