These are some common questions about the Type Annotations (JSR 308) extension to Java. Feel free to suggest improvements to the answers, or other questions to include here.
Before you read this FAQ, please read either the Type Annotations Specification (if you are most interested in the language syntax) or the Checker Framework Manual (if you are most interested in pluggable type-checking). Then, if you still have questions, you can see whether this FAQ answers them.
There is a separate FAQ for pluggable type-checking.
Contents:
@NonNull
?Type annotations make Java's annotation system more expressive and uniform. Thus, they can be used for many of the same purposes as Java 5's declaration annotations. A new use is as type qualifiers. Programmers can write these type qualifiers in their programs, and then a compiler plug-in automatically finds bugs.
No tool will solve all your problems, but pluggable type-checkers have been shown to help programmers to rid their programs of certain important classes of bugs, including null pointer errors, incorrect side effects, incorrect equality tests, and more. Users of the Checker Framework keep noticing new ways that pluggable type-checkers are useful, and you probably will too.
For more details, see the Checker Framework Manual and also section Example use of type annotations: Type qualifiers in the Type Annotations Specification.
The paper Practical pluggable types for Java discusses case studies in which programmers found type annotations to be natural to read and write. The code continued to feel like Java, and the type-checking errors were easy to comprehend and often led to real bugs.
You don't have to take our word for it, though. You can try the Checker Framework for yourself.
The difficulty of adding and verifying annotations depends on your program. If your program is well-designed and -documented, then skimming the existing documentation and writing type annotations is extremely easy. Otherwise, you may find yourself spending a lot of time trying to understand, reverse-engineer, or fix bugs in your program, and then just a moment writing a type annotation that describes what you discovered. This process inevitably improves your code. You must decide whether it is a good use of your time. For code that is not causing trouble now and is unlikely to do so in the future (the code is bug-free, and you do not anticipate changing it or using it in new contexts), then the effort of writing type annotations for it may not be justified.
In summary: annotations do not clutter code; they are used much less frequently than generic types, which Java programmers find acceptable; and they reduce the overall volume of documentation that a codebase needs.
As with any language feature, it is possible to write ugly code that over-uses annotations. However, in normal use, very few annotations need to be written. Figure 1 of the paper Practical pluggable types for Java reports data for over 350,000 lines of type-annotated code:
@NonNull
, @Nullable
, etc.)
@Interned
)
These numbers are for annotating existing code. New code that is written with the type annotation system in mind is cleaner and more correct, so it requires even fewer annotations.
Each annotation that a programmer writes replaces a sentence or phrase of English descriptive text that would otherwise have been written in the Javadoc. So, use of annotations actually reduces the overall size of the documentation, at the same time as making it less ambiguous and machine-processable.
Pluggable type-checking is a motivating application for type annotations. The Java specification for type annotations does not define any pluggable type-checkers; a pluggable type-checker is a separate tool.
There is a separate FAQ for pluggable type-checking.
Type annotations are part of Java 8.
The Type Annotations Specification (also known by its JCP codename "JSR 308") has received official final approval.
The Java language defines an annotation processing capability (JSR 269). Using this capability, it is possible to write annotation processors that read and process all sorts of annotations, including type annotations. Pluggable type-checking is one sort of annotation processing.
Pluggable type-checking would be impractical without the Type Annotations (JSR 308) language syntax. Given the new syntax, pluggable type-checking can be implemented entirely by libraries, and there is no need for it to be an official part of the Java language. The Checker Framework is an example of a library that enables you to create and use pluggable type-checkers.
The Checker Framework is an independent tool and not a part of the Type Annotations specification. The Checker Framework distribution includes the Type Annotations compiler for convenience, so that users only have to download and install one file.
The Type Annotations specification is freely available without any license, from the Type Annotations webpage. The specification places no restriction on compliant implementations.
An earlier version of the Type Annotations specification was published during an Early Draft Review (EDR) of JSR 308. The license used for the EDR contains certain restrictions. Obtaining the specification from the Type Annotations webpage does not impose any restrictions. Furthermore, it is more up-to-date than the EDR version, which is dated November 5, 2007.
You can use type annotations and custom type-checkers even if your
coworkers and users do not use custom type-checkers or the Type Annotations
compiler. You simply write the annotations in comments and use the Type
Annotations compiler, which recognizes comments containing type
annotations. Other developers can compile the annotated code using any
Java compiler, which will ignore the type annotations. The Type
Annotations compiler produces bytecodes that are identical to those
produced by javac, so the .class
files can be used in any JVM.
This also gives you an easy way to convince your colleagues to try type
annotations and the Checker Framework, or to use a
type-checker even if your colleagues do not want to.
For more details, see section
Writing
annotations in comments for backward compatibility in the Checker
Framework Manual.
Oracle's announced plan is to incorporate all of the changes in the Type Annotations compiler into the OpenJDK compiler, with the exception of the annotations in comments feature. The Oracle process for incorporating changes into OpenJDK is a lengthy one, so sometimes it takes a while before improvements to the Type Annotations compiler appear in OpenJDK.
Periodically, all public changes to the OpenJDK compiler are merged into the Type Annotations compiler. This can be done relatively easily, and without corporate approval required.
As a result, at any moment each compiler may have features the other one lacks. In general, you are better off using the Type Annotations compiler, particularly if you are interested in writing and checking type annotations.
For a more detailed description of the differences between the two compilers, see the Type Annotations compiler README file.
We have had successful reports from users of Linux, MacOS, and Windows. If you have trouble installing or running the tools, please report a bug. The Support section of the Type Annotations webpage explains how.
Yes, several IDEs support type annotations, and more IDEs are being extended to support type annotations. See the Running a checker section of the Checker Framework Manual.
You can download the Checker Framework, which includes the Type Annotations compiler and related tools, from Maven Central: https://search.maven.org/search?q=g:org.checkerframework.
The Checker Framework manual contains Maven usage instructions.
See the Support section of the Type Annotations webpage.
An annotation before a method sometimes refers to the return type, and sometimes to the method itself. There is never any ambiguity regarding which is intended. See section Target meta-annotations for type annotations in the Type Annotations specification.
@NonNull Object @Nullable []
?
@NonNull Object @Nullable []
is a possibly-null array of non-null
objects. Note that even though the first token in the type is
“@NonNull
”, that annotation applies to the element
type Object
. The annotation @Nullable
applies to the
array ([]
).
Similarly,
@Nullable Object @NonNull []
is a non-null array of possibly-null
objects.
If you are skeptical of the usefulness of the annotations, see section Uses for annotations on types in the Type Annotations specification. Also, section Receivers in the Type Annotations explains that receiver annotations have been necessary in every type system built to date.
If you are skeptical of the syntax of array annotations, then perhaps you really don't like Java's array syntax. The annotation extension is a logical extension of Java's syntax; see section Syntax of array annotations in the Type Annotations specification.
If you are skeptical of the syntax of receiver annotations, then you may be interested to learn that in a controlled experiment, the chosen receiver annotation syntax was nearly twice as understandable to beginners as the next best alternative.
While array and receiver annotations are critical in important circumstances, they are fairly rare in well-written code. And you don't have to use them if you don't want to.
Objects are not annotated — types or declarations are. Java has no run-time representation of the types of the variables that refer to an object. The Type Annotations specification (JSR 308) enriches types, but it does not change that fundamental property. Type annotations as implemented in JSR 308 have no run-time representation. This means that they impose no run-time burden on Java programs that use them.
Reflective calls can query the class of an object, or can query the type annotations on source code.
Statement annotations are within the scope of JSR 308. However, this feature will not be a part of the initial version of JSR 308. A future revision could add them.
Perhaps it should. Feel free to suggest modifications or additions to that section. Your edits should correct factual errors, or should be well-motivated by compelling use-cases that cannot be achieved by other means.
@NonNull
?Defining annotations is beyond the scope of the Type Annotations Specification, whose purpose is to lay the groundwork so that others can define such types.
Type Annotations (JSR 308) is a language extension that makes existing and
future annotations more useful to programmers. By contrast, Annotations
for Software Defect Detection (JSR 305) defines some specific annotations,
such as @Nonnull
and @Positive
. The JSR 305 annotations
are most useful if they can be written on types, so JSR 305 would need JSR 308
to achieve its full potential.
JSR 305 has been abandoned; there has been no activity by its expert
group since 2009.
The Type Annotations (JSR 308) expert group gladly welcomes suggestions for improvements to the Type Annotations specification, and to the tools that support it.
A JSR, or Java Specification Request, is a proposed specification for some aspect of the Java platform — the Java language, virtual machine, libraries, etc. For more details, see the Java Community Process FAQ. Many people refer to the Type Annotations specification by its JCP codename, “JSR 308”.
Last updated: April 30, 2021.
Back to the Type annotations (JSR 308) webpage.