Java源码中有意思的代码片段

154 查看

无聊时,看了一下java.util.Collections源码,发现一个有趣的代码片段。下面这段代码是从java.util.Collections中Copy出来的,大看一下有趣在哪里??

public static int indexOfSubList(List<?> source, List<?> target) {
    int sourceSize = source.size();
    int targetSize = target.size();
    int maxCandidate = sourceSize - targetSize;

    if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
        (source instanceof RandomAccess&&target instanceof RandomAccess)) {
    nextCand:
        for (int candidate = 0; candidate <= maxCandidate; candidate++) {
            for (int i=0, j=candidate; i<targetSize; i++, j++)
                if (!eq(target.get(i), source.get(j)))
                    continue nextCand;  // Element mismatch, try next cand
            return candidate;  // All elements of candidate matched target
        }
    } else {  // Iterator version of above algorithm
        ListIterator<?> si = source.listIterator();
    nextCand:
        for (int candidate = 0; candidate <= maxCandidate; candidate++) {
            ListIterator<?> ti = target.listIterator();
            for (int i=0; i<targetSize; i++) {
                if (!eq(ti.next(), si.next())) {
                    // Back up source iterator to next candidate
                    for (int j=0; j<i; j++)
                        si.previous();
                    continue nextCand;
                }
            }
            return candidate;
        }
    }
    return -1;  // No candidate matched the target
}

上面有个语法这样的:

nextCand:
        for (int candidate = 0; candidate <= maxCandidate; candidate++) {
            ListIterator<?> ti = target.listIterator();
            for (int i=0; i<targetSize; i++) {
                if (!eq(ti.next(), si.next())) {
                    // Back up source iterator to next candidate
                    for (int j=0; j<i; j++)
                        si.previous();
                    continue nextCand;
                }
            }
            return candidate;
        }

这样的语法很少见,可以说几乎在Java根本没有,一开始我还以是反编译时编译出错了,出现了语法错误,但是我好奇的试了一下这个语法,真是奇了,竟然可以通过编译,程序也能正常运行。

下面是我的代码:

public class Test {
    
    public static void main(String[] args) {
        
        isNext : for (int i = 0; i < 5; i++) {
                if ((i % 2) != 0) {
                    continue isNext;
                }
                System.out.println("i ==> " + i);
            }
    }
}

运行结果:

程序不没有报错,可以正常运行,运行的结果和我们使用标准的 for 循环一样。从上面的运行结果可以看出 continue isNext 的作用和 continue 一样,都是跳出当前循环。

说道这里,我们分析一样一下这个语言的使用场景,先看一下语法。

identifies :  
    code segment {
        break/continue identifies;
    }

identifies 是自定义的,定义的规则个Java的参数定义一样,如果冒号后面跟的的循环,可以使用 break identifies 跳出整个循环,或 continue identifies 退出当前循环。其实最上面的源码中,就有注解: // Element mismatch, try next cand(元素不匹配,尝试下一个元素),当然,我还发现另一种用法,那就是,冒号后面跟着方法,也可以执行方法。


eg: for(;;;) {continue identifies}

public static void isNext1() {
    // for(;;;) {continue identifies}
    isNext1 : for (int i = 0; i < 5; i++) {
        if ((i % 2) != 0) {
            continue isNext1;
        }
        System.out.println("i ==> " + i);
    }
}

eg: do...while() {break identifies}

public static void isNext2() {
    // do...while() {break identifies}
    isNext2 : do {
        System.err.println("while() {break identifies}");
        if (true) {
            break isNext2;
        }
    } while (true);
}

eg: do...while() {break identifies}

public static void isNext3() {
    // while() {break identifies}    
    isNext3 : while (true) {
        System.err.println("do...while() {break identifies}");
        if (true) {
            break isNext3;
        }
    }
}

eg: switch() {break identifies}

public static void isNext4() {
    // switch() {break identifies}
    isNext4 : switch (1) {
        case 1:
            System.err.println("switch() {break identifies}");
            break isNext4;
        default:
            break isNext4;
    }
}

eg: method()

public static void isNext5() {
    isNext : test(11);
}

public static void test(int arg) {
    System.err.println("method() ==> " + arg);
}

总结

这种语法就是用来装逼的,没有什么软用。O(∩_∩)O哈哈哈~