List.addAll() 什么时候抛出 IllegalStateException?

When does List.addAll() throw IllegalStateException?

我有密码

private List<Field> subFields;
private Collection<Field> subFieldsCollection;

...

try {
    if (subFields == null && subFieldsCollection != null && !subFieldsCollection.isEmpty()) {
        subFields = new ArrayList<>();
        subFields.addAll(subFieldsCollection);
    }
} catch (IllegalStateException e) {
    ...
}

我想知道 IllegalStateException 怎么会被抛出。它显然发生在我的应用程序的用户身上,但我无法追踪问题所在。

Collection.addAll() 的文档说:

IllegalArgumentException - if not all the elements can be added at this time due to insertion restrictions

但是插入限制是什么?

我想这取决于集合的确切类型。我正在使用 ArrayList,所以让我们检查 List 接口的 addAll() 的文档:

IllegalArgumentException - if some property of an element of the specified collection prevents it from being added to this list

嗯,什么元素 属性 可以阻止将元素添加到列表中?我的两个集合属于同一类型,我应该可以添加空值..

有人能给我解释一下吗?

我不知道任何抛出 IllegalArgumentException 的实现(在 jre 或任何库中)。

但是您可以轻松地创建自己的实现,从而抛出此类异常。接口 Collection 让用户知道,实现者 可以 使用 IllegalArgumentException - 它没有说,实现者 实际上 [=] =33=] 使用它。

一个例子:

import java.util.ArrayList;


public class PickyList<T> extends ArrayList<T> {

    public static class SpecialThing {

    }

    @Override
    public boolean add(T e) {
        if (e instanceof SpecialThing)
            return super.add(e);
        throw new IllegalArgumentException();
    }

}

因此我推荐这种方法:

  • 检查您的代码,您正在向 collection 添加 语义上合理的 项目。不要将 objects of class Person 添加到名为 postalCodes
  • 的列表中
  • 适当的方式处理任何技术运行时异常。例如回滚事务,记录日志,通知用户 and/or 支持团队
  • 考虑通知您的方法的调用者(通过 JavaDoc),您的方法可能会失败

您的代码永远不会抛出 IllegalArgumentException,因为 ArrayList#addAll 无法抛出此类异常。

为了获得该异常,您必须使用 class 实现 Collection 可以抛出此类异常。您可以通过扩展 ArrayList 和重写相关方法轻松创建自己的方法。

这确实取决于实施。如果您在 the documentation 中检查 ArrayList,这是您实际使用的 class,您会看到这个。

Throws: NullPointerException - if the specified collection is null

所以你的 ArrayList 不应该抛出 IllegalArgumentException。如果您将使用另一个实现或包装器(请参阅 unmodifiable list注意 此示例不会抛出此类异常),它可能会抛出此类异常。

所以从您的用户那里获取日志记录并尝试重现该问题。

根据您从用户那里获得的信息量,这可能无法回答。但我会做出猜测,如果有更多证据与它相悖,我会删除我的答案。 :)

假设你写了所有的代码,我同意 addAll() 不能抛出 IllegalStateException(所有关于 IllegalArgumentException 的讨论都是无关紧要的)。

我的猜测是该错误并非源自 addAll() 调用,而是代码中的另一个调用(未显示)试图操纵其中一个集合。它 可能通过尝试获得 IllegalStateException ,例如,遍历列表(使用通过 .iterator() 获得的迭代器)并删除一个项目,然后尝试在不调用 Iterator.next() 的情况下删除另一个项目。类似地,Iterator.set() 可以在从 ArrayList 获得的迭代器中抛出一个。所以我的猜测是,在操纵列表的某个地方,发生了这些事情之一。

或者,其他 集合实现可以通过多种方式抛出一个。因此,如果我们不确定它是否与 ArrayList 相关,那么我们就没什么可继续的了。