java retry:详解
发现
今天在探秘线程池原理知识点,在阅读JDK源码时遇到程序代码中出现如下代码,因为之前没有遇到过,于是特地记录下来并谷歌了一番,后面我自己做了一些简要的验证和分析。

验证
网上溜达一番发现,这retry就是一个标记,标记对一个循环方法的操作(continue和break)处理点,功能类似于goto,所以retry一般都是伴随着for循环出现,retry:标记的下一行就是for循环,在for循环里面调用continue(或者break)再紧接着retry标记时,就表示从这个地方开始执行continue(或者break)操作,具体我们来看看下面的例子:
1、使用continue跳出循环的操作:
public static void testContinue() {
retry:
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.print(j + ", ");
if(j == 3) {
continue retry;
}
}
}
System.out.print(" >>> OK");
}
// 输出:0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, >>> OK
2、使用breank跳出循环的操作:
public static void testBreak() {
retry:
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.print(j + ", ");
if(j == 3) {
break retry;
}
}
}
System.out.print(" >>> OK");
}
// 输出:0, 1, 2, 3, >>> OK
从上面的两个例子可以看出,在内层循环里面调用continue(或者break)后接着retry标识符,程序直接转到最外层for循环去处理了。
揭秘
我多想了一下,这个retry标记的使用原理是什么样的?于是我扒了扒上面程序的反编译代码,希望能够从中找到答案:
public static void testContinue()
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++)
{
System.out.print(j + ", ");
if (j == 3) {
break;
}
}
}
System.out.print(" >>> OK");
} public static void testBreak()
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++)
{
System.out.print(j + ", ");
if (j == 3) {
break label59;
}
}
}
label59:
System.out.print(" >>> OK");
}
很明显,编译的时候编译器自动按照程序逻辑转换成了我们日常使用的方式来处理,比如continue的语句则翻译成了break,而下面的break方法同样使用了标记位,只是顺序不同了而已,这和程序执行的逻辑顺序应该是有关系的,显然编译器很聪明,如果你不加for循环下面的那一个关于OK的打印语句,编译器就直接把break retry;转换成了return;语句,说明编译器已经知道在这里根据逻辑来判断和处理了。
启发
这一个标记的作用,给了我们一点点启发,因为平时好像都没有怎么见到过这个使用方法,但是类似跳出多重循环的场景却不在少数,看看以前我们都是怎么样处理的。
1、跳出里面的for循环,继续从外面for循环开始执行:
public static void testContinueR() {
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.print(j + ", ");
if(j == 3) {
break;
}
}
}
}
使用break直接结束里面这一层循环,然后从外出for循环继续开始。
2、跳出里外两层循环,直接往下执行逻辑:
public static void testBreakR() {
boolean flag = false;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.print(j + ", ");
if(j == 3) {
flag = true;
break;
}
}
if(flag) {
break;
}
}
System.out.println(" >>> OK");
}
其实这里有两种情况,如果for循环后面没有内容了,可以直接在最里层循环执行return语句,如果后面还有其他逻辑执行,那么可以使用标记位辅助。
总结
如果你现在积累到了这个retry标记的用法,这个地方就可以更加灵活的处理了,可以不用写那么多的辅助代码,还有一点需要提一下,其实这个retry标识符不是指定的,只要任意符合Java变量命名的标识符都可以,只要后面接上英文冒号就行了。
public static void testOtherFlag() {
abc:
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
System.out.print(j + ", ");
if(j == 3) {
break abc;
}
}
}
}
// 输出:0, 1, 2, 3,
其实和goto有同样争议的是,在过于复杂的循环程序里面使用这个标记,可能会降低程序的可读性,所以在使用之前,还是需要自己权衡。
java retry:详解的更多相关文章
- Java内部类详解
Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...
- 黑马----JAVA迭代器详解
JAVA迭代器详解 1.Interable.Iterator和ListIterator 1)迭代器生成接口Interable,用于生成一个具体迭代器 public interface Iterable ...
- C++调用JAVA方法详解
C++调用JAVA方法详解 博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...
- Java虚拟机详解----JVM常见问题总结
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- [转] Java内部类详解
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- Java面向对象详解
Java面向对象详解 前言:接触项目开发也有很长一段时间了,最近开始萌发出想回过头来写写以前学 过的基础知识的想法.一是原来刚开始学习接触编程,一个人跌跌撞撞摸索着往前走,初学的时候很多东西理解的也懵 ...
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- java 泛型详解(普通泛型、 通配符、 泛型接口)
java 泛型详解(普通泛型. 通配符. 泛型接口) JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0.这说明Java已经有大幅度的变化.本文将讲解JDK5.0支持的新功能---- ...
- Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
随机推荐
- Latex:插入伪代码
*本文属于转载. *转载链接:https://blog.csdn.net/lwb102063/article/details/53046265 目录 clrscode algorithm algori ...
- 【转】MySQL innodb_autoinc_lock_mode 详解 ,并发插入时主键冲突的解决方案
本文转载于 http://www.cnblogs.com/JiangLe/p/6362770.html innodb_autoinc_lock_mode这个参数控制着在向有auto_increment ...
- strcpy和strncpy用法和区别
1. strcpy函数:顾名思义字符串复制函数:原型:extern char *strcpy(char *dest,char *src); 功能:把从src地址开始且含有NULL结束符的字符串赋值到以 ...
- 关于dispatch_sync死锁问题
首先,我们来看下下面一个例子: 代码:(串行队列里同步线程嵌套) NSLog(@"haha"); dispatch_queue_t queue = dispatch ...
- javascript 内置日期转换方法
var d = new Date(); console.log(d); // 输出:Mon Nov 04 2013 21:50:33 GMT+0800 (中国标准时间) console.log(d.t ...
- monkey测试工具与常用的linux命令
Monkey测试工具 说明:monkey是一个安卓自带的命令行工具,可以模拟用户向应用发起一定的伪随机事件.主要用于对app进行稳定性测试与压力测试. 实现:首先需要安装一个ADB工具,安装完之后,需 ...
- python 获得列表中每个元素出现次数的最快方法
import collections import numpy as np import random import time def list_to_dict(lst): dic = {} for ...
- Linux中的more命令
ore命令,功能类似 cat , cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,而且还有搜寻 ...
- Verlet Integration
Verlet Integration Verlet 积分法是一种用于求解牛顿运动方程的数值方法,被广泛运用于动力学模拟以及视频游戏中.尔莱算法的优点在于:数值稳定性比简单的欧拉方法高很多,并保 ...
- BZOJ4033 [HAOI2015]树上染色 【树形dp】
题目 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间 ...