2016年12月20日 星期二

[Java] For的陷井

今天在用迴圈時,發現一個現像,紀錄下來

以下這段程式碼A


public static void main(String[] args) {
        
        String[] date=new String[]{"a'","'b"};
     
        for( String str : date)
        {
            str=str.replace("'", "");
        }
        
        for( String str : date)
        {
            System.out.println(str);
        }
               
    }

輸出結果為

a'
'b


而以下這段程式碼B


 public static void main(String[] args) {
        
        String[] date=new String[]{"a'","'b"};
     
        for( int i=0;i<date.length;i++)
        {
            date[i]=date[i].replace("'", "");
        }
        
        for( String str : date)
        {
            System.out.println(str);
        }
               
    }

輸出結果為

a
b


我們發現A程式並沒有實際去改變date陣列中的值,而B程式碼會。

我們再看一下以下這段程式碼C ,比較物件的記憶體位址 ,在未進行replace前,

str與date[index]記憶體位址是相同的,但進行replace後,重新設定了str的值,對

foreach來說,改變它的值,相當於重新new一塊記憶體位址,而不是去改變原本記憶體位

所以原本位置的值是不會改變的。


    public static void main(String[] args) {
        
        String[] date=new String[]{"a'","'b"};
     
        int index=0;
        for( String str:date)
        {   
           System.out.println("index="+ index+  " address equals: "+ (str == date[index]));
        
           str=str.replace("'", "");
           
           System.out.println("index="+ index+  " address equals: "+ (str == date[index]));
           index++;
        }
        
        for( String str : date)
        {
            System.out.println(str);
        }
               
    }

輸出結果如下:

index=0 address equals: true
index=0 address equals: false
index=1 address equals: true
index=1 address equals: false
a'
'b


如果我們把String 改成int呢


public static void main(String[] args) {
        
        int[] date=new int[]{1,2};
     
        int index=0;
        for( int str:date)
        {   
           System.out.println("index="+ index+  " address equals: "+ (str == date[index]));
        
           str=str+10;
           
           System.out.println("index="+ index+  " address equals: "+ (str == date[index]));
           index++;
        }
        
        for( int str : date)
        {
            System.out.println(str);
        }
               
    }

輸出結果如下

index=0 address equals: true
index=0 address equals: false
index=1 address equals: true
index=1 address equals: false
1
2


即使是int,依然是無法修改,原因在於JAVA For Each做法


是將陣列中的值,依序COPY到 str中,但你改變str時 ,則會另外配置一塊記憶體。


使用Foreach處理陣列時,需注意這一個限制。


參考下列連結:

http://chris800731.blogspot.tw/2013/08/javaforeach-foreach-in-java.html


沒有留言:

張貼留言