ImmutableList does not extend List?

こ雲淡風輕ζ 提交于 2019-12-21 12:59:41

问题


When I dig into the gs-collection source for ImmutableList, it does not extends java.util.List. However the class javadoc mentioned that All ImmutableList implementations must implement the java.util.List.

Why must ask the implementation to implement java.util.List and not the ImmutableList itself to extend java.util.List?


回答1:


Why doesn't ImmutableList extend List?

ImmutableCollection doesn't extend java.util.Collection (and ImmutableList doesn't extend java.util.List) because Collection has mutating methods like add() and remove(). If immutable collections had these methods, they would always have to throw UnsupportedOperationException. For users of immutable collections, it would be strange to see add() and remove() in auto-complete choices as callable methods.

Why does the Javadoc impose a contract that all ImmutableList implementations also implement List?

It comes down to equality. An ImmutableList ought to equal a List, assuming both lists have the same contents in the same order. List.equals() imposes a Javadoc contract which states:

Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.

What does it mean that "the specified object is also a list?" We can see in AbstractList.equals() that it means instanceof List.

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;
    ...
}

So all ImmutableList implementations must also implement List for equals() to work in a symmetric way. The immutable collection factories already hide implementation details like the fact that an immutable list with a single element is implemented by an ImmutableSingletonList. It also winds up hiding the List interface.

Interop

A benefit of this design is that ImmutableList can be cast to List which is important for interop with existing APIs.

// Library method - cannot refactor the parameter type
public void printAll(List<?> list)
{
    for (Object each : list)
    {
        System.out.println(each);
    }
}

ImmutableList<Integer> immutableList = Lists.immutable.with(1, 2, 3);
List<Integer> castList = immutableList.castToList();
printAll(castList);
// also works
printAll((List<?>) immutableList);

// throws UnsupportedOperationException
castList.add(4);

Note: I am a developer on GS Collections.



来源:https://stackoverflow.com/questions/29504881/immutablelist-does-not-extend-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!