com.surelogic
Annotation Type Immutable


@Documented
@Target(value={TYPE,FIELD,CONSTRUCTOR,METHOD,PARAMETER})
public @interface Immutable

When used on a class or interface declaration, this annotation declares that instances of the annotated type are always immutable. When used on a field or parameter, this annotation indicates that the field or parameter has an immutable reference (see below). When used on a method or constructor, this annotation indicates that the receiver or return value (or both) is an immutable reference.

An immutable reference cannot be used to modify the state of referenced object. Furthermore, no other references to the referenced object may be used to modify the state of the object either. The state of the object will never change. In contrast, a ReadOnly reference may not be used to modify the state of the referenced object, but the object may have other non-read only aliases that can be used to modify the state of the object. Immutable references are not currently checked by analysis.

Instances of the type (class or interface) to which this annotation is applied are immutable. This means that its state cannot be seen to change by callers, which implies that

Immutable objects may still have internal mutable state for purposes of performance optimization; some state variables may be lazily computed, so long as they are computed from immutable state and that callers cannot tell the difference. Such practices may or may not be verifiable by a tool, such as SureLogic JSure. (Use of the Vouch annotation can be used, especially annotation of @Vouch("Immutable") on a field, to suppress overly conservative tool results.)

This annotation is currently verified, but not defined, by restricting how the fields of the class are declared and annotated. This is a conservative, although easily understood, way to verify the Immutable assertion. Specifically, for a class annotated as @Immutable to be verified, each field must be

Immutable objects are inherently thread-safe; they may be passed between threads or published without synchronization. Therefore instances of an Immutable type are also ThreadSafe, but not necessarily visa versa.

Typically, subtypes of the annotated type must be explicitly annotated @Immutable as well. It is a modeling error if they are not. This annotation has two attributes, implementationOnly and verify, that control how subtypes of an Immutable type must be annotated. The implementationOnly attribute indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes. There are several rules with regards to the implementationOnly attribute on Immutable types:

  1. The implementationOnly attribute must be false when Immutable appears on an interface, because interfaces do not have an implementation.
  2. The subinterfaces of an interface annotated with Immutable must be annotated with Immutable; classes that implement an interface annotated with Immutable must be annotated with @Immutable(implementationOnly=false).
  3. The superclass of a class annotated with @Immutable(implementationOnly=true) must be annotated with @Immutable(implementationOnly=true); there are no constraints on the subclasses.
  4. The superclass of a class annotated with @Immutable(implementationOnly=false) must be annotated with either @Immutable(implementationOnly=false) or @Immutable(implementationOnly=true); the subclasses must be annotated with @Immutable(implementationOnly=false).
Finally, it may be possible to implement a class that satisfies the semantics of Immutable, but that is not verifiable using the syntactic and annotation constraints described above. For this case, we provide the "escape hatch" of turning off tool verification for the annotation with the verify attribute. For example, @Immutable(verify=false) would skip tool verification entirely.

A type may not be annotated with both @Immutable and @Mutable.

Relationship with @ThreadSafe

Thread safety and immutability are two points along the same axis. This set of annotations can actually describe three points along the axis:

@Mutable and @NotThreadSafe
This is the same as being unannotated, or just @Mutable, or just @NotThreadSafe. The type contains mutable state that is not safe to access concurrently from multiple threads.
@Mutable and @ThreadSafe
This is the same as @ThreadSafe. The type contains mutable state that is safe to access concurrently from multiple threads.
@Immutable and @ThreadSafe
This is the same as @Immutable. The type contains no mutable state, and is thus safe to access concurrently from multiple threads.

The combination @Immutable and @NotThreadSafe is a modeling error because an immutable type is obviously thread safe.

An @Immutable interface may extend a @ThreadSafe interface. An @Immutable class may implement a @ThreadSafe interface.

A @ThreadSafe class may extend a class annotated with @Immutable(implementationOnly=true).

Semantics:

Instances of the type to which this annotation is applied are thread-safe and their state cannot be seen to change by callers.

Examples:

The immutable Point class below is considered thread-safe.
 @Immutable
 public class Point {
 
   final int f_x;
   final int f_y;
 
   @Unique("return")
   @RegionEffects("none")
   public Point(int x, int y) {
     f_x = x;
     f_y = y;
   }
 
   @RegionEffects("reads Instance")
   public int getX() {
     return f_x;
   }
 
   @RegionEffects("reads Instance")
   public int getY() {
     return f_y;
   }
 }
 
A @Vouch("Immutable") annotation is used to express that a private array is immutable after object construction. Because the Java language does not allow the programmer to express that the contents of the array are unchanging, use of a Vouch is necessary in this example.
 @Immutable
 public class Aircraft {
 
   @Vouch("Immutable")
   private final Wing[] f_wings;
 
   @Unique("return")
   @RegionEffects("none")
   public Aircraft() {
     f_wings = new Wing[2];
     f_wings[0] = new Wing();
     f_wings[1] = new Wing();
   }
   ...
 }
 

Javadoc usage notes:

This annotation may placed in Javadoc, which can be useful for Java 1.4 code which does not include language support for annotations, via the @annotate tag.
 /**
  * @annotate Immutable
  */
 public class Point {
   ...
 }
 
 /**
  * @annotate Immutable
  */
 public class KeyTimes implements Iterable {
   /**
    * @annotate Vouch("Immutable")
    */
   private final List<Double> f_keyTimes;
 
   ...
 }
 
 /**
  * @annotate Immutable
  */
 public class Aircraft {
 
   /**
    * @annotate Vouch("Immutable")
    */
   private final Wing[] f_wings;
   
   ...
 }
 
Implementation note: This annotation is derived from @Immutable proposed by Brian Goetz and Tim Peierls in the book Java Concurrency in Practice (Addison-Wesley 2006) we have simply adapted it to have semantics as a promise. Further, the annotation in net.jcip.annotations may be used instead of this one with the same tool behavior. One difference between the two annotations is that the annotation in com.surelogic adds the implementationOnly and verify attributes—these attributes can not be changed from their default values if the the net.jcip.annotations annotation is used. Another difference is that the annotation in net.jcip.annotations has retention policy of RetentionPolicy.RUNTIME while the annotation in com.surelogic has a retention policy of RetentionPolicy.CLASS.

See Also:
ThreadSafe, Mutable, Vouch, ReadOnly

Optional Element Summary
 boolean implementationOnly
          Indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes.
 String value
          When annotating a constructor or a method, this attribute must be "this" or "return" to clarify the intent that it is the receiver that is immutable.
 boolean verify
          Indicates whether or not tool verification should be attempted.
 

implementationOnly

public abstract boolean implementationOnly
Indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes.

Returns:
true if only the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes, false otherwise. The default value for this attribute is false.
Default:
false

verify

public abstract boolean verify
Indicates whether or not tool verification should be attempted.

Returns:
true if the claim should be verified by a tool, such as SureLogic JSure, false otherwise. The default value for this attribute is true.
Default:
true

value

public abstract String value
When annotating a constructor or a method, this attribute must be "this" or "return" to clarify the intent that it is the receiver that is immutable. It is a modeling error if the attribute is not "this" or "return" in this case. When annotated on a constructor "this" or "return" have equivalent semantics.
 class C {
   @Immutable("this")
   public C() { ... }
 
   @Immutable("return")
   void method() { ... }
   ...
 }
 
This attribute is only used when annotating a constructor or method; it is a modeling error for the value to be anything other than the default when annotating a type or a parameter.
 int proc(@Immutable int value       /* Illegal: Parameter has primitive type */, 
          @Immutable Object settings /* Legal: Parameter has reference type */) { ... }
 
The value of this attribute must conform to the following grammar (in Augmented Backus–Naur Form):
 value = ["this" / "return"] ; See above comments
 

Default:
""


Copyright © 2011 Surelogic, Inc.. All Rights Reserved.