缺少 return 语句而不抛出新的 IllegalArgumentException

missing return statement without throw new IllegalArgumentException

我正在查看 leetcode 两和代码,对抛出新的 IllegalArgumentException 语句感到困惑。代码的目标是 return 两个数字的索引,以便在给定整数数组的情况下将它们加起来达到特定目标。假设每个输入都有一个解决方案,并且您不能两次使用相同的元素。这是代码:

如果我 运行 此代码没有抛出 new IllegalArgumentException("No two sum solution"),它会显示错误消息:

Line 10: error: missing return statement } ^

但是如果我添加 throw new IllegalArgumentException("No two sum solution"),代码 运行 就会很顺利。

我的问题是,既然假设每个输入只有一个解决方案,为什么抛出新的 IllegalArgumentException 在这种情况下很重要。 谢谢。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums [j] == target) {
                    return new int[] {i, j};
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

编译器无法知道您关于只有一种解决方案的假设。

关于语句可达性的规则实际上是非常基本的。特别是,因为存在外循环上的循环保护而不是值为 true 的常量表达式,编译器认为循环体可能永远不会执行。因此,您需要处理这种可能性。

因为该方法是 non-void,您必须 return 一个值或抛出异常。

欢迎来到 SO!

编译器将分析您的代码,并需要使用适当的退出语句终止通过您的代码可以到达的每条路径。

由于您向 return 声明了一个整数数组,因此每条路径都必须指向声明类型的 return 语句 return 的结尾。

因为你只能到达你的 if 里面的 return 你的 for 里面的 for,编译器可以很容易地找到绕过它的方法:

for (int i = 0; i < nums.length; i++) {

如果num.length == 0将不会被输入。因为你不检查这个,即使是一个聪明的编译器也必须期望一个空数组作为有效输入(即使是 null 也是有效的 - 并且会使你的函数崩溃)

for (int j = i + 1; j < nums.length; j++) {

同样,需要 num.length > j。由于 num.length==1 是有效输入,因此您不会进入此 for 循环。

if (nums[i] + nums [j] == target) {

return 语句的最后一个障碍完全取决于数组的内容和 target 的值。由于这些值仅在运行时已知,并且编译器对它事先不知道的事情有点 mimimi,它会期望您提供许多将无法满足此条件的输入,因此永远不会达到 return。

因此,编译器可以很容易地看出,code-paths 没有正确的 return 语句。抛出异常是另一种终止语句,因此会让您的编译器满意。