如何避免Java方法中无用的返回

问题

我有一种情况,理论上总是会到达嵌套在两个for循环中的return语句。编译器不同意并要求在for循环之外使用return语句。我想知道一种优雅的方法来优化这种方法,这超出了我目前的理解,我尝试的中断实现似乎都不起作用。 Attached是一种来自赋值的方法,它生成随机整数并返回循环的迭代,直到找到第二个随机整数,在作为int参数传递给方法的范围内生成。

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) { // Run until return.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.   
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                return count;
            }
        }
    }
    return 0; // Never reached
}

#1 热门回答(341 赞)

编译器的启发式方法永远不会让你省略las​​treturn。如果你确定它永远不会到达,我会用athrow替换它以使情况清楚。

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    for (int count = 1; count <= range; count++) {
        ...
    }

    throw new AssertionError("unreachable code reached");
}

#2 热门回答(35 赞)

As@BoristheSpider pointed out你可以确保第二个return语句在语义上不可达:

private static int oneRun(int range) {
    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    int count = 0;

    while (true) {
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                return count;
            }
        }
        count++;
    }
}

编译并运行良好。如果你得到an000082128,你会知道实现在语义错误,而不必显式抛出任何东西。


#3 热门回答(17 赞)

由于你询问了两个150044289个循环的中断,你可以使用标签来执行此操作(请参阅下面的示例):

private static int oneRun(int range) {
    int returnValue=-1;

    int[] rInt = new int[range+1]; // Stores the past sequence of ints.
    rInt[0] = generator.nextInt(range); // Inital random number.

    OUTER: for (int count = 1; count <= range; count++) { // Run until return.
        rInt[count] = generator.nextInt(range); // Add randint to current iteration.   
        for (int i = 0; i < count; i++) { // Check for past occurence and return if found.
            if (rInt[i] == rInt[count]) {
                returnValue = count;
                break OUTER;
            }
        }
    }
    return returnValue;
}