今天发现了个奇怪的问题,直接看代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54package bingfa; import com.sun.javaws.IconUtil; import java.util.concurrent.ForkJoinPool; public class ForeachTest { private class Node{ private int num; private Node(int num) { this.num = num; } public int get() { return num; } } Node[] n1 = {new Node(1),new Node(2),new Node(3),new Node(4),new Node(5),new Node(6),}; Node[] n2 = {new Node(11),new Node(22),new Node(33),new Node(44),new Node(55),new Node(66),}; public void test() throws InterruptedException { Thread t1 = new Thread(() -> { for (Node n : n1) { System.out.println(n.get()); if (n.get() == 3) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); Thread t2 = new Thread(() -> { n1 = n2; System.out.println("t2"); }); t1.start(); Thread.sleep(1); t2.start(); } public static void main(String[] args) { ForeachTest f = new ForeachTest(); try { f.test(); } catch (InterruptedException e) { e.printStackTrace(); } } } output: 1 2 3 t2 4 5 6
简单来说,这段代码要验证的东西是,使用foreach时,如果被遍历的对象的引用被更改了,那么它依然是遍历原先的对象。
现在,我将foreach改为for(int i=0;i<n1.length;i++):
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65package bingfa; import com.sun.javaws.IconUtil; import java.util.concurrent.ForkJoinPool; public class ForeachTest { private class Node{ private int num; private Node(int num) { this.num = num; } public int get() { return num; } } Node[] n1 = {new Node(1),new Node(2),new Node(3),new Node(4),new Node(5),new Node(6),}; Node[] n2 = {new Node(11),new Node(22),new Node(33),new Node(44),new Node(55),new Node(66),}; public void test() throws InterruptedException { Thread t1 = new Thread(() -> { for (Node n : n1) { System.out.println(n.get()); if (n.get() == 3) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); Thread t2 = new Thread(() -> { n1 = n2; System.out.println("t2"); }); Thread t3 = new Thread(() -> { for (int i = 0;i < n1.length;i++) { System.out.println(n1[i].get()); if (n1[i].get() == 3) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }); t3.start(); Thread.sleep(1); t2.start(); } public static void main(String[] args) { ForeachTest f = new ForeachTest(); try { f.test(); } catch (InterruptedException e) { e.printStackTrace(); } } } output: 1 2 3 t2 44 55 66
此时输出结果跟foreach的就不一样了,它遍历的就是修改后的n2。
总结:
当使用foreach遍历数组对象时,即使中途数组对象的引用被更改,那么也不会影响遍历的结果,除非是数组中的对象被更改;而使用数组下标遍历数组对象时,不论是数组对象的引用被更改,还是数组中的对象被更改,都会影响最后的结果。
个人认为,当使用foreach的时候,它应该会自己生成一个隐含的变量指向被遍历的对象,所以最初的引用改不改的都没关系了。而使用数组下标遍历时则不会生成这个隐含的变量。
最后
以上就是受伤水池最近收集整理的关于JAVA--foreach与数组的全部内容,更多相关JAVA--foreach与数组内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复