Recall that immutability offers several benefits such as thread-safety, prevention against inadvertent modification of fields, and malicious tampering. Class invariants and state of immutable objects are always consistent with their requirements, so no defensive copying is necessary. However, sometimes it is not possible to make sensitive classes immutable. Fortunately, there is a mechanism that allows code to expose mutable classes to untrusted code by granting read-only access. This is largely achieved through unmodifiable wrappers. For example, in the Collection
classes include a set of wrappers that allow clients to observe an unmodifiable view of the particular Collection
object.
...
This noncompliant code example consists of class Modifiable
, which allows the internal ArrayList
object to be modified. An untrusted invoker may call the mutator method listIt()
and violate the object's immutability property.
...
It should be noted that objects present within the Collection
may not be thread-safe, making them mutable in multithreaded contexts. Consider, for example, an ArrayList
of ArrayLists
wherein the contained ArrayList
is still susceptible to modification.
...
This noncompliant code example shows an interface MutableInterface
which that declares an accessor and a mutator method. This class does not expose an unmodifiable view to implementing clients.
...
In general, sensitive classes can be transformed into safe-view objects by implementing all the methods defined by the core interface, including the mutator methods. In this case, the difference is that the mutators need to throw an UnsupportedOperationException
so that clients cannot carry out perform operations that affect the immutability property of the object.
This compliant solution constructs an UnmodifiableSensitiveMutable
by extending the class SensitiveMutable
. An interface UnmodifiableInterface
consists of the method unmodifiableView()
, which accepts a SensitiveMutable
object as the sole parameter. It returns an equivalent object that is a subtype of the same class , and which is unmodifiable. An exception is thrown if the caller attempts to use the mutator method on the returned object. This object can be passed to untrusted code as required.
...