为什么要添加' AbstractCollection中的方法不是抽象的?

时间:2014-05-27 12:26:27

标签: java collections abstract

public abstract class AbstractCollection<E> implements Collection<E> {
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

方法add(E e)不是抽象的,而是在扩展抽象类时抛出异常。遵循这种方法有什么好处?如果方法被抽象化,那么它必须强制覆盖并节省一些混淆。

3 个答案:

答案 0 :(得分:2)

如果您尝试修改任何不可修改的集合,则抛出UnsupportedOperationException是标准行为。例如,它由 Collections.unmodifiable 包装器(当前有八个)返回的类的所有变量方法抛出,例如Collections.unmodifiableList,以及不可变的Collections.emptyList以及所有迭代器。

因此,AbstractCollection.add(E)抛出此异常只是为了通过提供有用的默认行为来更容易实现不可修改的集合。您将看到在所有这些方法中也实现了相同的行为:

  

(此外,默认情况下,许多方法都会抛出异常,这些方法不会故意抛出它,但会调用哪些方法,例如AbstractList.clear())。

  

如果方法变得抽象,那么它必须强制覆盖并节省一些混淆。

可能,但是有许多地方需要不可修改的行为,因此拥有默认实现可能很方便。它还鼓励不可修改的集合始终如一地抛出异常;否则有人可能会通过让它无所事事而不是抛出异常来实现add方法,这会让人更加困惑。

当您需要可修改的集合时,只需查看您扩展的Abstract*基类的文档,这将始终说明您需要覆盖哪些其他方法。例如,AbstractCollection says

  

要实现不可修改的集合,程序员只需要扩展此类并提供iteratorsize方法的实现。 (iterator方法返回的迭代器必须实现hasNextnext。)

     

要实现可修改的集合,程序员必须另外覆盖此类的add方法(否则会抛出UnsupportedOperationException),并且iterator方法返回的迭代器必须另外实现其remove方法。

答案 1 :(得分:1)

并非所有收藏品都是可变的。这个默认实现可以很容易地实现不可变集合。

答案 2 :(得分:0)

the Javadoc中的答案:

  

如果一个集合因为已经包含该元素的原因而拒绝添加特定元素,那么它必须抛出一个异常(而不是返回false)。这保留了在此调用返回后集合始终包含指定元素的不变量。

这个想法是,如果方法成功执行,您就知道元素在集合中。