THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

Unmodifiable wrappers are a reasonable way to expose information that may be changing but that shouldn't
be changed by the observer. For example, consider the Attributed interface and the AttributedImpl
class from Chapter 4. The attributes are exposed by having the attrs method return an Iteratora
reasonable design. An alternative, however, would be to return the attributes as an unmodifiable collection.
Here's how AttributedImpl could implement this:


public Collection attrs() {
return Collections.
unmodifiableCollection(attrTable.values());
}


Generally, iterators must be used immediately after they are obtained from the iterator method, with no
intervening changes to the collectionotherwise, use of the iterator will encounter a
ConcurrentModificationException. In contrast, you can ask for an unmodifiable collection, and
then use it at some later time when the original collection has undergone arbitrary changes. Exposing
information via a collection also allows the users of your class to utilize all the Collection utility methods.
For example, if you expose your information as an unmodifiable list, it can be searched and sorted without
your having to define search and sort methods.


21.10.3. The Checked Wrappers


A List is guaranteed at compile time to only ever hold String objectsunless you have to pass
it to legacy code as a raw type, in which case all guarantees are off (and you will get an "unchecked"
warning). Dealing with legacy code that is unaware of generic types is a practical necessity. However,
tracking down problems can be difficult. If you pass a List to a legacy method that erroneously
inserts a Number, you won't discover the problem until another part of your code tries to force the Number
to be a String. The type-safe checked wrappers have been provided to help you with this problem. A
checked wrapper will make a runtime check to enforce the type safety lost when the collection is used as a
raw type. This allows errors to be detected as soon as they occurwhen that erroneous Number is inserted.


public static <E> Collection<E>checkedCollection(Collection<E>
coll, Class<E> type)

Returns a dynamically typeset view of the given collection. Any attempt to
insert an element that is not of the specified type will result in a
ClassCastException.

The other type checked wrappers are obtained from checkedList, checkedSet,
checkedSortedSet, checkedMap, and checkedSortedMap.


21.11. Synchronized Wrappers and Concurrent Collections


All the collection implementations provided in java.util are unsynchronized (except the legacy
collections you will soon see). You must ensure any necessary synchronization for concurrent access from
multiple threads. You can do this explicitly with synchronized methods or statements, or algorithmically
by designing your code to use a given collection from only one thread. These techniques are how collections
are often naturally usedas local variables in methods or as private fields of classes with synchronized code.


Thread-safety for collection classes themselves takes two main forms: lock-based synchronization to ensure
that concurrent access is precluded, and the use of sophisticated data structures that allow (to varying degrees)
truly concurrent use of a collection. The former is provided through the synchronized wrappers, while the

Free download pdf