@Documented @Retention(value=RUNTIME) @Target(value=TYPE) public @interface AnnotationBounds
@Containable, @Immutable,
@ReferenceObject, @ThreadSafe, and
@ValueObject annotations to the formal type parameters.
Annotating a type formal this way establishes a bound on the type actual that
may be passed to the type when the generic type is instantiated. For example,
consider the generic class C
@AnnotationBounds(containable="T")
public class C<T> {
…
}
The type formal T has the annotation bound
@Containable, meaning that it can only be instantiated with
a type actual A such that the implementation of
A is containable.
Annotation bounds are ultimately used to satisfy the assurance of a
@Containable, @Immutable, or
@ThreadSafe annotation on a type. Consider
@Immutable
@AnnotationBounds(immutable="W")
public class Wrapper<W> {
private final W wrapped;
@RegionEffects("none")
@Unique("return")
public Wrapper(final W w) {
wrapped = w;
}
…
}
For the implementation of Wrapper to be assured to be immutable,
the field wrapped must have an immutable type. Thus we must
declare the annotation bound @Immutable on the type formal
W. When the type Wrapper is instantiated to a
parameterized type, the type actual passed to W must have an
immutable implementation. The following parameterized types would be
acceptable:
Wrapper<String>
Wrapper<Integer>
Wrapper<T>, where T is a type formal in
scope that has @Immutable as an annotation bound
The following parameterized types would not be acceptable:
Wrapper<Object>
Wrapper<int[]>
Wrapper<T>, where T is a type formal in
scope that does not have @Immutable as an annotation bound
The attributes of the annotation are arrays of strings, where each string is the name of a formal type parameter of the type being annotated. It is illegal to name a type parameter of a type that encloses or is enclosed by the type being annotated. The examples below show legal uses of the annotation:
// X and Y must have thread safe implementations
@AnnotationBounds(threadSafe={"X", "Y"})
public class C<X, Y> { … }
// A must have an immutable implementation
// B must have a containable implementation
// C is unconstrained
@AnnotationBounds(immutable="A", containable="B")
public class D<A, B, C> { … }
If a type formal is named in more than one attribute of this annotation an or semantics is used. That is,
@AnnotationBounds(threadSafe="A", referenceObject="A")
public class Example<A> { … }
means that the actual type passed to a A must be a thread safe
or reference type. When Example is assured, it must be
correct under either assumption. The following class would not assure, for
example:
@ThreadSafe
@AnnotationBounds(threadSafe="A", referenceObject="A")
public class Bad<A> {
private final A field;
}
Class Bad does not assure because its own @ThreadSafe
annotation only assures when A is assumed to be thread safe; it
does not assure when A is assumed to be a reference type.
The thread-safe collection classes in java.util and
java.util.concurrent are annotated with this annotation to
enforce that the elements placed in the collection are also thread safe.
Specifically, thread safe maps such as Hashtable and
ConcurrentHashMap are annotated such that the formal type parameters
K and V for the key and value types are bounded by
@ThreadSafe, while thread safe lists such as CopyOnWriteArrayList
and BlockingQueue are annotated such that the formal type for the
element type E is bounded by @ThreadSafe. Consider the
example below:
public class Example {
private List<String> names; // not checked
private List<? extends List<String>> listOfLists; // not checked
public void initForConcurrent() {
names = new CopyOnWriteArrayList<String>(); // GOOD
listOfLists = new CopyOnWriteArrayList<CopyOnWriteArrayList<String>>(); // GOOD
}
public void initForSequential() {
names = new ArrayList<String>(); // not checked
listOfLists = new ArrayList<List<String>>(); // not checked
}
public ConcurrentMap<Location, Player> getGameMap() { … } // GOOD
}
@ThreadSafe
public class Location { … }
@ThreadSafe
public class Player { … }
The parameterized types in the field declarations do not need to be checked
by analysis because the type formal of List is unbounded. Similarly,
the parameterized types in initForSequential() do not need to
be checked by analysis because the type formals of List and
ArrayList are unbounded. But the parameterized types in
initForConcurrent do need to be checked because the type formal
of CopyOnWriteArrayList is bounded. Of note is the fact that we
must use the parameterized type CopyOnWriteArrayList<String>
as the actual type parameter to new CopyOnWriteArrayList<…>
because we must provide a type that is known to be thread safe.
The return type of getGameMap() must also be checked by
analysis because ConcurrentMap has bounded type formals. In this
case, the bounds are satisfied because the classes Location
and Player are thread safe.
Containable,
Immutable,
ReferenceObject,
ThreadSafe,
ValueObject| Modifier and Type | Optional Element and Description |
|---|---|
String[] |
containable
Indicates that the named formal type parameters of the annotated class
should be assumed to be
@Containable. |
String[] |
immutable
Indicates that the named formal type parameters of the annotated class
should be assumed to be
@Immutable. |
String[] |
referenceObject
Indicates that the named formal type parameters of the annotated class
should be assumed to be
@ReferenceObject. |
String[] |
threadSafe
Indicates that the named formal type parameters of the annotated class
should be assumed to be
@ThreadSafe. |
String[] |
valueObject
Indicates that the named formal type parameters of the annotated class
should be assumed to be
@ValueObject. |
public abstract String[] containable
@Containable. Specifically, the
value of this attribute is an array of formal type parameter names.public abstract String[] immutable
@Immutable. Specifically, the
value of this attribute is an array of formal type parameter names.public abstract String[] referenceObject
@ReferenceObject. Specifically,
the value of this attribute is an array of formal type parameter names.public abstract String[] threadSafe
@ThreadSafe. Specifically, the
value of this attribute is an array of formal type parameter names.public abstract String[] valueObject
@ValueObject. Specifically,
the value of this attribute is an array of formal type parameter names.Copyright © 2012 Surelogic, Inc.. All Rights Reserved.