Is guava's ImmutableXXX really immutable?

前端 未结 3 1417
陌清茗
陌清茗 2021-01-05 01:23

I have been using guava for some time now and truly trusted it, until I stumbled of an example yesterday, which got me thinking. Long story short, here it is:



        
相关标签:
3条回答
  • 2021-01-05 01:55

    The list itself is immutable because you cannot add/remove elements. The elements are on their own regarding immutability. In more precise terms, we have definitions from a historical Java 1.4.2 document:

    • Collections that do not support any modification operations (such as add, remove and clear) are referred to as unmodifiable. Collections that are not unmodifiable are referred to modifiable.
    • Collections that additionally guarantee that no change in the Collection object will ever be visible are referred to as immutable. Collections that are not immutable are referred to as mutable.

    Note that for these definitions to make any sense we must assume an implicit distiction between a collection in an abstract sense and an object that represents that collection. This is important because the object that represents an immutable collection is not itself immutable by any standard definition of that term. For example, its equals relation has no temporal consistency, a vital requirement on immutable objects.

    As far as defensive copying, note that is an ill-defined problem in general and there will never be a general immutable collection in Java that will manage to defensively copy its elements. Note additionally that such a collection would be less useful than the immutable collections that really exist: when you put an object into a collection, in 99.99% cases you want that very object to be there, not some other object that is not even equal to it.

    There is a quite standard definition of object immutability (as opposed to collection immutability) which assumes transitive immutability of the whole object graph reachable from the immutable object. Taken too literally, though, such a definition will almost never be satisfied in the real world. Two cases in point:

    • nothing is immutable in the face of reflection. Even final fields are writable.
    • even String, that bastillon of immutability, has been proven mutable outside the Java sandbox (without a SecurityManager—which covers 99% of real-world Java programs).
    0 讨论(0)
  • 2021-01-05 01:55

    You mix the immutability of the list and the immutability of the objects it contains. In an immutable collection you cannot add/remove objects, but if the object it contains are mutable you can modify them after get()ing them.

    0 讨论(0)
  • 2021-01-05 01:57

    What you're getting at here is the difference between immutable and deeply immutable.

    An immutable object will never change, but anything that it refers to might change. Deep immutability is much stronger: neither the base object nor any object you can navigate to from it will change.

    Each is appropriate in its own situations. When you create your own class that has a field of type Date, that date is owned by your object; it's truly a part of it. Therefore, you should make defensive copies of it (on the way in and the way out!) to provide deep immutability.

    But a collection does not really "own" its elements. Their states are not considered part of the collection's state; it is a different type of class -- a container. (Furthermore, as you allude, it has no deep knowledge of what element type is being used, so it wouldn't know how to copy the elements anyway.)

    Another answer states that the Guava collections should have used the term unmodifiable. But there is a very well-defined difference between the terms unmodifiable and immutable in the context of collections, and it has nothing to do with shallow vs. deep immutability. "Unmodifiable" says you cannot change this instance, via the reference you have; "immutable" means this instance cannot change, period, whether by you or any other actor.

    0 讨论(0)
提交回复
热议问题