Java标签跳转:一个鲜为人知但却很实用的小技巧
在C系风格的代码中,标签是一个容易掌握但是却很难熟练使用的特性,容易主要体现在其规则简单,配合goto很容易就能实现一些比较复杂的逻辑。很难熟练使用主要是体现在对于复杂场景下,不好对流程把控,调试,也不好维护,是典型的面向过程的特性。
前两天在看jdk源码的时候,无意中看到线程池中这个方法的源码:
1 private boolean addWorker(Runnable firstTask, boolean core) { 2 retry: 3 for (int c = ctl.get();;) { 4 // Check if queue empty only if necessary. 5 if (runStateAtLeast(c, SHUTDOWN) 6 && (runStateAtLeast(c, STOP) 7 || firstTask != null 8 || workQueue.isEmpty())) 9 return false; 10 11 for (;;) { 12 if (workerCountOf(c) 13 >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK)) 14 return false; 15 if (compareAndIncrementWorkerCount(c)) 16 break retry; 17 c = ctl.get(); // Re-read ctl 18 if (runStateAtLeast(c, SHUTDOWN)) 19 continue retry; 20 // else CAS failed due to workerCount change; retry inner loop 21 } 22 } 23 .....
我一开始以为标签是配合goto 用的,但是仔细一看没有goto 字段,是配合 break,continue来使用的。
详细查了下这个特性,其实很简单。主要是在代码块来使用,总体来说存在两种使用场景
场景一:
在普通代码块中,配合break关键字使用:
在代码块前边声明一个标签,当执行代码块时,如果发现需要提前结束代码块,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )直接break 标签即可。
普通代码块既可以是 {} 直接包裹的方法,也可以是if/else 语句的代码块
依次来看这几个例子
(1)普通代码块
1 public class Label1 { 2 static int i = 1; 3 4 public static void main(String[] args) { 5 step1: 6 { 7 i++; 8 if (i == 2) { 9 break step1; 10 } 11 i = 3; 12 } 13 System.out.println("i is :" + i); 14 } 15 }
输出结果如下:
i is :2
(2)if代码块
1 public class Label2 { 2 static int i = 0; 3 public static void main(String[] args) { 4 i++;//i = 1 5 step2: 6 if (i != 0) { 7 i++; 8 if (i == 2) { 9 break step2; 10 } 11 i = 3; 12 } 13 System.out.println("i is :" + i); 14 } 15 }
输出结果如下:
i is :2
(3)else 代码块
public class Label3 { static int i = 1; public static void main(String[] args) { i++; if (i == 0) { i = 10; } else step3:{ i++; if (i == 3) { break step3; } i = 5; } System.out.println("i is :" + i); } }
输出结果如下:
i is :3
以前看有人些写的代码,喜欢使用这种伪代码块(或者叫做业内常叫「伪块 / 一次性代码块) ,其实都一个意思
do { //do sth } while (false);
然后通过break来随时控制,do sth内部的逻辑来提前结束,其实大可不必。只要用标签加普通代码块的格式即可简单实现易读易理解的代码了。
场景二:
在标签关联的循环中,配合break/continue 来操作。我们知道如果在多层循环,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )内循环想直接退出外层循环,或者直接重新开始外层循环是很繁琐的。但是配合标签,就好处理的多了。
我们以do while加while来举例子:
public class Label4 { public static void main(String[] args) { int i = 100; step4: do { while (true) { if (i <= 105) { i++; System.out.println("current i is" + i); continue step4; } i = i + 100; System.out.println("current i is" + i); if (i > 300) { break step4; } i--; } } while (true); } }
输出结果如下:
current i is101
current i is102
current i is103
current i is104
current i is105
current i is106
current i is206
current i is305
如果你觉得写的不错,欢迎转载和点赞。 转载时请保留作者署名jilodream/王若伊_恩赐解脱(博客链接:http://www.cnblogs.com/jilodream/

浙公网安备 33010602011771号