在学习CopyonWriteArrayList的源码中,发现了这么一段代码:
private boolean remove(Object o, Object[] snapshot, int index) { //加锁 final ReentrantLock lock = this.lock; lock.lock(); try { //获取数组 Object[] current = getArray(); int len = current.length; //判断传进来的数组是否和现数组相等 if (snapshot != current) findIndex: { //获取索引和现有长度的最小值 int prefix = Math.min(index, len); for (int i = 0; i < prefix; i++) { if (current[i] != snapshot[i] && eq(o, current[i])) { index = i; break findIndex; } } if (index >= len) return false; if (current[index] == o) break findIndex; index = indexOf(o, current, index, len); if (index < 0) return false; } Object[] newElements = new Object[len - 1]; System.arraycopy(current, 0, newElements, 0, index); System.arraycopy(current, index + 1, newElements, index, len - index - 1); setArray(newElements); return true; } finally { lock.unlock(); } }
这其中用到了findIndex: 这样一个结构,第一次遇到这样的结构体,询问同事,同事说可能是c语言中的goto语句,仔细观看源码后,就发现,如果是goto语句,那么只要snapshot 数组和 current数组 不相等,那么这就是一个死循环,一直回到if判断哪里。于是我又去看其它分析CopyonWriteArrayList 的文章,发现这个findIndex: 这是指类似方法体的东西,将括号后面的内容当做一个整体,只要出现break findIndex 就跳出整个方法体,执行方法体之后的代码。
实例代码如下:
public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); findIndex:{ for (String s : list) { if(s.equals("2")){ break findIndex; } } System.out.println(2); } System.out.println(1); }
但执行这段代码,会发现,break findIndex 跳出的不是for循环,而是跳出findIndex 方法体,
如果把break 这里的 findIndex 去除,那么这里还是会打印2出来。