为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在 Java 中迭代 Empty Map 不会引发任何异常

为什么在 Java 中迭代 Empty Map 不会引发任何异常

素胚勾勒不出你 2021-11-17 14:59:27
我遇到了下面的代码,我希望 Java 能够通过异常,因为我正在迭代的 List 是空的。public static void main(String[] args) {   final List<Map<String, Object>> candidateList = new ArrayList<>();    for (final Map<String, Object> candidate : candidateList) {        if (candidate.isEmpty()) {            System.out.println("Empty!!!");        }    }}但是代码执行时没有抛出任何错误或异常。
查看完整描述

3 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

解释

您正在使用增强的 for 循环:


for (final Map<String, Object> candidate : candidateList) {

    ...

}

编译器将其替换为与以下源代码等效的字节码:


Iterator<Map<String, Object>> elementIter = candidateList.iterator();

while (elementIter.hasNext()) {

    final Map<String, Object> candidate = elementIter.next();

    ...

}

如果不再有下一个元素,虽然elementIter.next()确实会抛出 a NoSuchElementException(请参阅文档),但首先检查循环条件:


while (elementIter.hasNext()) {

并在您的情况下Iterator#hasNext返回false。请参阅文档:


true如果迭代有更多元素,则返回。(换句话说,return trueifnext()会返回一个元素而不是抛出异常。)


所以你的循环永远不会进入。这也是为什么您不会看到循环设计者所希望的任何异常的原因。


与常规循环的比较

为了进行比较,让我们尝试使用常规循环迭代一个空数组:


int[] values = new int[0];


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

    System.out.println(values[i]);

}

代码运行良好,没有任何异常,原因与之前相同。条件解决为


i < 0

对于第一次迭代 ( i = 0),这已经是错误的。所以永远不会进入循环。


这意味着增强的 for 循环的行为与常规循环的此示例相同。


查看完整回答
反对 回复 2021-11-17
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

库设计者决定不抛出异常,因为他们认为这将使使用库的代码更干净。如果它确实抛出了一个异常,你必须每次都检查集合是否为空,而不是仅仅迭代它并依赖于什么都不发生。

设计师在不同的情况下做出了不同的决定。例如,Iterables.find(iterable, predicate)如果不存在与谓词匹配的元素,当它可能刚刚返回null等时,Guava 会抛出异常。

用于决定是否抛出异常的经验法则是:如果使用参数的调用很可能是由错误进行的,或者可能会产生难以调试的错误,则抛出异常。否则做一些明智的事情(比如返回null,无操作等)

因此,尝试迭代一个空集合被认为不太可能是错误的,而尝试查找集合中不存在的元素被认为可能是意外的,从而导致异常。但这些并不是硬性规定,视角因语言而异,因设计者而异,因情况而异。


查看完整回答
反对 回复 2021-11-17
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

public static void main(String[] args) {

   final List<Map<String, Object>> candidateList = new ArrayList<>();

    for (final Map<String, Object> candidate : candidateList) {

        //because all below code will never execute

        if (candidate.isEmpty()) {

            System.out.println("Empty!!!");

        }

    }

}

它永远不会进入你的循环,所以它不会抛出任何异常。


如果您将空元素添加到您的列表中。它会抛出错误


查看完整回答
反对 回复 2021-11-17
  • 3 回答
  • 0 关注
  • 151 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信