@Documented @Retention(value=RUNTIME) @Target(value={METHOD,CONSTRUCTOR}) public @interface Deterministic
==
) every time it is called with the same
parameters and in the same environment. The parameters include the
receiver, and the environment includes all of the Java heap (that is,
all fields of all objects and all static variables).
This annotation is important to pluggable type-checking because, after a
call to a @Deterministic
method, flow-sensitive type refinement
can assume that anything learned about the first invocation is true
about subsequent invocations (so long as no non-@
SideEffectFree
method call intervenes). For example,
the following code never suffers a null pointer
exception, so the Nullness Checker need not issue a warning:
if (x.myDeterministicMethod() != null) {
x.myDeterministicMethod().hashCode();
}
Note that @Deterministic
guarantees that the result is
identical according to ==
, not equal according to
equals
. This means that writing @Deterministic
on a
method that returns a reference is often erroneous unless the
returned value is cached or interned.
Also see Pure
, which means both deterministic and SideEffectFree
.
Analysis:
The Checker Framework performs a conservative analysis to verify a
@Deterministic
annotation. The Checker Framework issues a
warning if the method uses any of the following Java constructs:
Deterministic
.
@Deterministic
int f() {
try {
int b = 0;
int a = 1/b;
} catch (Throwable t) {
return t.hashCode();
}
return 0;
}
@Pure
, but a constructor invocation is
not deterministic since it returns a different new object each time.
TODO: Side-effect-free constructors could be allowed to set their own fields.
Note that the rules for checking currently imply that every Deterministic
method is also SideEffectFree
. This might change
in the future; in general, a deterministic method does not need to be
side-effect-free.
These rules are conservative: any code that passes the checks is deterministic, but the Checker Framework may issue false positive warnings, for code that uses one of the forbidden constructs but is deterministic nonetheless.
In fact, the rules are so conservative that checking is currently
disabled by default, but can be enabled via the
-AcheckPurityAnnotations
command-line option.