慣例先看一段代碼java
public class DemoCollection14 { public static void main(String[] args) { String [] strs = {"zs", "ls", "wu"}; for (String str : strs) { strs[0] = null; System.out.println(str); } for (String str : strs) { System.out.println(str); } } } //輸出: // zs // ls // wu // // null // ls // wu 要想搞懂這道題,先看下面講解
從新學習數組(此處引用了廖雪峯老師的講解)數組
數組是引用類型,而且數組大小不可變學習
public class Main { public static void main(String[] args) { // 5位同窗的成績: int[] ns; ns = new int[] { 68, 79, 91, 85, 62 }; System.out.println(ns.length); // 5 ns = new int[] { 1, 2, 3 }; System.out.println(ns.length); // 3 } }
數組大小變了嗎?看上去好像是變了,但其實根本沒變。spa
對於數組ns
來講,執行ns = new int[] { 68, 79, 91, 85, 62 };
時,它指向一個5個元素的數組:code
ns │ ▼ ┌───┬───┬───┬───┬───┬───┬───┐ │ │68 │79 │91 │85 │62 │ │ └───┴───┴───┴───┴───┴───┴───┘
執行ns = new int[] { 1, 2, 3 };
時,它指向一個新的3個元素的數組:對象
ns ──────────────────────┐ │ ▼ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ │68 │79 │91 │85 │62 │ │ 1 │ 2 │ 3 │ │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
可是,原有的5個元素的數組並無改變,只是沒法經過變量ns
引用到它們而已。ci
若是數組元素不是基本類型,而是一個引用類型,那麼,修改數組元素會有哪些不一樣?字符串
字符串是引用類型,所以咱們先定義一個字符串數組:get
String[] names = { "ABC", "XYZ", "zoo" };
對於String[]
類型的數組變量names
,它實際上包含3個元素,但每一個元素都指向某個字符串對象:io
┌─────────────────────────┐ names │ ┌─────────────────────┼───────────┐ │ │ │ │ │ ▼ │ │ ▼ ▼ ┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┐ │ │░░░│░░░│░░░│ │ "ABC" │ │ "XYZ" │ │ "zoo" │ │ └───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┘ │ ▲ └─────────────────┘
對names[1]
進行賦值,例如names[1] = "cat";
,效果以下:
┌─────────────────────────────────────────────────┐ names │ ┌─────────────────────────────────┐ │ │ │ │ │ │ ▼ │ │ ▼ ▼ ┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┬───────┬───┐ │ │░░░│░░░│░░░│ │ "ABC" │ │ "XYZ" │ │ "zoo" │ │ "cat" │ │ └───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┴───────┴───┘ │ ▲ └─────────────────┘
這裏注意到原來names[1]
指向的字符串"XYZ"
並無改變,僅僅是將names[1]
的引用從指向"XYZ"
改爲了指向"cat"
,其結果是字符串"XYZ"
再也沒法經過names[1]
訪問到了。
對「指向」有了更深刻的理解後,試解釋以下代碼:
public class Main { public static void main(String[] args) { String[] names = {"ABC", "XYZ", "zoo"}; String s = names[1]; names[1] = "cat"; System.out.println(s); // s是"XYZ"仍是"cat"? } } //輸出"XYZ" //解釋緣由: //names字符串數組建立好後,s指向names[1]這個位置。 //可是呢,name[1]可不是把原數據XYZ更改成了cat,而是從新指向了存有cat的那個空間地址。 //故s仍是指向原來那個位置,故輸出的是XYZ
再回到開始的那個問題:
public class DemoCollection14 { public static void main(String[] args) { String [] strs = {"zs", "ls", "wu"}; for (String str : strs) { strs[0] = null; System.out.println(str); } for (String str : strs) { System.out.println(str); } } } //輸出: // zs // ls // wu // // null // ls // wu foreach,其實就是迭代器。迭代器,不是傳統意義的for循環輸出數組數據。 而是定義了String str,依次str=strs[i],並輸出str。故和前面的xyz,性質同樣了。