惯例先看一段代码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,性质同样了。