今天在阅读FutureTask的源码时,读到下面一段代码,百思不得其解。若说是个全局变量吧,又没有声明,局部也没有声明,而且retry又不是Java关键字,这种写法之前也没见过。于是Google了一些资料,终于了解了它的作用,特意写出来与大家分享。
2.2 案例 2.2.1 正常的continue语句retry:其实就是个标记位,标记程序跳出循环之后从哪里执行,类似于C语言中的goto语句。retry:一般都是伴随for循环语句出现的,retry:下一行跟的就是for循环语句,在for循环里面调用continue retry;(或者break retry;),就表示从这个地方开始执行continue(或者break)操作。
@Slf4j
public class RetryDemo1 {
public static void main(String[] args) {
log.info("main方法开始执行+++++");
for (int i = 0; i < 3; i++) {
log.info("第一层循环:i={}", i);
for (int j = 0; j < 5; j++) {
if (j == 3) {
log.info("第二层循环结束:i={},j={}", i, j);
continue;
}
log.info("第二层循环:i={},j={}", i, j);
}
}
log.info("循环结束+++++++");
}
}
运行结果为:
这段代码是一个双重循环,当满足第二个循环中j==3时,continue会跳出当前循环,因而后面的打印语句未执行,所以并未输出:
第二层循环:i=0,j=3 第二层循环:i=1,j=3 第二层循环:i=2,j=32.2.2 正常的break语句
@Slf4j
public class RetryDemo2 {
public static void main(String[] args) {
log.info("main方法开始执行+++++");
for (int i = 0; i < 3; i++) {
log.info("第一层循环:i={}", i);
for (int j = 0; j < 5; j++) {
if (j == 3) {
log.info("第二层循环结束:i={},j={}", i, j);
break;
}
log.info("第二层循环:i={},j={}", i, j);
}
}
log.info("循环结束+++++++");
}
}
运行结果为:
与2.2.1节代码类似,将该案例中的continue换成了break,发现第二层循环执行到j==3后,由于break导致循环提前结束,因而未打印:
第二层循环:i=0,j=3 第二层循环:i=0,j=4 第二层循环:i=1,j=3 第二层循环:i=1,j=4 第二层循环:i=2,j=3 第二层循环:i=2,j=42.2.3 continue retry语句
@Slf4j
public class RetryDemo3 {
public static void main(String[] args) {
log.info("main方法开始执行+++++");
retry:
for (int i = 0; i < 3; i++) {
log.info("第一层循环:i={}", i);
for (int j = 0; j < 5; j++) {
if (j == 3) {
log.info("第二层循环结束:i={},j={}", i, j);
continue retry;
}
log.info("第二层循环:i={},j={}", i, j);
}
}
log.info("循环结束+++++++");
}
}
上述代码运行结果为:
将上图结果与2.2.1节正常运行的continue结果进行对比,发现这里少打印了:
第二层循环:i=0,j=4 第二层循环:i=1,j=4 第二层循环:i=2,j=4
这是因为我们的retry:埋点在第一个for循环上,当执行到语句continue retry;时,会跳出当前此次循环,跳到我们标记的第一个for循环继续执行,因此第二个循环体不会打印j=4的语句。
2.2.4 break retry语句@Slf4j
public class RetryDemo4 {
public static void main(String[] args) {
log.info("main方法开始执行+++++");
retry:
for (int i = 0; i < 3; i++) {
log.info("第一层循环:i={}", i);
for (int j = 0; j < 5; j++) {
if (j == 3) {
log.info("第二层循环结束:i={},j={}", i, j);
break retry;
}
log.info("第二层循环:i={},j={}", i, j);
}
}
log.info("循环结束+++++++");
}
}
上述代码运行结果为:
这个结果出现的原因是:当执行到j==3时,会进如判断语句,执行break retry;跳出循环到最外层循环,外层循环只执行了一次就break了,所以i=1,i=2的结果都未打印。
为了验证上述代码的区别,反编译2.2.3节代码,反编译后结果如下:
同时反编译2.2.4节代码,结果如下:
由上述反编译结果可知,编译器将continue retry;翻译成了break语句,下面的break retry;同样添加了标记位,翻译成了break语句,只是break位置不一样,说明根据不同的语境编译器做了处理。这段代码的本质体现了这个语句就是在程序某个位置埋置了一个break语句而已。
其实上述代码中retry可以改成任何符合java命名规范的名称,将上述代码中的retry换成abc,代码同样能正常执行并输出结果,如下图所示:
1.retry本质其实就是个标记位,标记程序跳出循环之后从哪里执行,类似于C语言中的goto语句;
2.retry后一般接循环语句,循环语句内会用continue retry;或break retry;指定在某个具体的逻辑跳出;
3.retry只是一个变量,可以被任何符合java编码的名称所替换。
1.https://blog.csdn.net/qing_gee/article/details/103364266
2.https://www.cnblogs.com/captainad/p/10931314.html



