发现

今天在探秘线程池原理知识点,在阅读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:详解的更多相关文章

  1. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  2. 黑马----JAVA迭代器详解

    JAVA迭代器详解 1.Interable.Iterator和ListIterator 1)迭代器生成接口Interable,用于生成一个具体迭代器 public interface Iterable ...

  3. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

  4. Java虚拟机详解----JVM常见问题总结

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  5. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  6. Java面向对象详解

    Java面向对象详解 前言:接触项目开发也有很长一段时间了,最近开始萌发出想回过头来写写以前学 过的基础知识的想法.一是原来刚开始学习接触编程,一个人跌跌撞撞摸索着往前走,初学的时候很多东西理解的也懵 ...

  7. 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 ...

  8. java 泛型详解(普通泛型、 通配符、 泛型接口)

    java 泛型详解(普通泛型. 通配符. 泛型接口) JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0.这说明Java已经有大幅度的变化.本文将讲解JDK5.0支持的新功能---- ...

  9. Java synchronized 详解

    Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...

随机推荐

  1. Python PycURL的安装使用

    PycURL中文简介:https://blog.csdn.net/qq_41185868/article/details/80487014 PycURL英文简介(如下):http://pycurl.i ...

  2. 使用TensorFlow的卷积神经网络识别手写数字(3)-识别篇

    from PIL import Image import numpy as np import tensorflow as tf import time bShowAccuracy = True # ...

  3. install redis and used in golang on ubuntu 14.04

    $ wget http://download.redis.io/releases/redis-3.0.3.tar.gz$ tar xzf redis-3.0.3.tar.gz$ cd redis-3. ...

  4. 安装go 1.5 & 部署

    https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz tar -C /usr/local -xzf go1.5.linux-am ...

  5. 【MySQL】MySQL备份和恢复

    一.为什么要备份数据 在生产环境中我们数据库可能会遭遇各种各样的不测从而导致数据丢失, 大概分为以下几种. 硬件故障 软件故障 自然灾害 黑客攻击 误操作 (占比最大) 所以, 为了在数据丢失之后能够 ...

  6. 树状数组 - BZOJ 1103 [POI2007]大都市

    bzoj 1103 [POI2007]大都市 描述 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员 Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景. ...

  7. day03_11 if语句实现猜年龄01

    老男孩猜年龄游戏 age_of_princal = 56 guess_age = int( input(">>:") ) #以下为伪代码 ''' if guess_ag ...

  8. getattr、setattr、hasattr

    写一个演示类 class test(): title="验证getattr.setattr.hasattr方法" def run(self): return "run方法 ...

  9. jQUery中的$(document).ready()方法和window.onload()方法的区别

    1.常规的Javascript代码中,通常使用window.onload方法 window.onload = function(){//代码} 2.jquery中,则使用$(document).rea ...

  10. HDU-1529 Cashier Employment

    据网上说这是到差分约束四星题... 可我觉得难吗? 比推DP方程容易... 两种约束方式,当然实现到程序就变成六种了... #include <cstdio> #include <c ...