Basic Java Annotations
Usage
Gradle (Kotlin DSL)
compileOnly(group = "pl.tlinkowski.annotation", name = "pl.tlinkowski.annotation.basic", version = "x.y.z")
Gradle (Groovy DSL)
compileOnly group: 'pl.tlinkowski.annotation', name: 'pl.tlinkowski.annotation.basic', version: 'x.y.z'
Maven
<dependency>
<groupId>pl.tlinkowski.annotation</groupId>
<artifactId>pl.tlinkowski.annotation.basic</artifactId>
<version>x.y.z</version>
<scope>provided</scope>
</dependency>
JPMS (module-info.java
)
requires static pl.tlinkowski.annotation.basic;
Purpose
The purpose of this library is to provide a couple of basic annotations related to the following concepts:
Nullability
The approach to nullability taken by this library is:
Everything is non-null by default, unless explicitly annotated as nullable.
This approach is directly in line with Kotlin's approach (although Kotlin enforces it through its type system):
String
(Kotlin) /String
(Java) → non-nullString
String?
(Kotlin) /@NullOr String
(Java) →null
orString
For this purpose, the library provides two annotations in the pl.tlinkowski.annotation.basic
package:
-
-
affects: all type uses (e.g. fields, method return types, method parameters, type parameters, local variables) and type parameters within the annotated package
-
analogous to (except for the scope of affected entities):
@NonNullApi
+@NonNullFields
in Spring;@ParametersAreNonnullByDefault
in JSR 305
-
-
target: type uses (e.g. fields, method return types, method parameters, type parameters, local variables) and type parameters
-
affects: annotated type use
-
analogous to (except for the scope of allowed targets):
@Nullable
in Spring;@CheckForNull
in JSR-305
-
The annotations in this library are based on the dormant Java Specification Request JSR 305. JSR 305 has been chosen for this library after analyzing the following pros & cons.
To sum up, even though I'd rather not rely on JSR 305, it seems too well supported right now to discard it.
However, should the state of JSR 305 change in favor of dropping its usage, this library will do just that. The purpose of this library is to provide @NonNullPackage
and @NullOr
annotations that work in the best currently possible way.
Mutability
The approach to mutability of Collection
s (but also Iterator
s) taken by this library is:
Every use of
Collection
orIterator
should be annotated with either@ReadOnly
or@Mutable
.
This approach is in line with Kotlin's approach (although Kotlin enforces it through its type system):
-
List<T>
(Kotlin) /@ReadOnly List<T>
(Java) → read-only list ofT
-
MutableList<T>
(Kotlin) /@Mutable List<T>
(Java) → mutable list ofT
For this purpose, this library includes two annotations in the kotlin.annotations.jvm
package (as a transitive dependency on kotlin-annotations-jvm
):
-
-
target: fields, methods, parameters, or local variables
-
affects: annotated type use
-
-
-
target: fields, methods, parameters, or local variables
-
affects: annotated type use
-
There are three main problems with these annotations, though:
-
According to Denis Zharkov, these annotations will probably be renamed once KT-23812 is done.
-
These annotations are JDK6-compatible, and hence they cannot target type uses or type parameters (introduced in JDK 8). There's an issue about improving this (KT-28982), but it seems idle now.
-
These annotations are not retained at runtime (
@Retention(RetentionPolicy.CLASS)
), which could be useful (at least theoretically).
To sum up, the main reason this library does not introduce its own annotations is that Kotlin wouldn't recognize them, and they are very useful for Kotlin interop. However, once KT-23812 is done, this library will probably migrate to some new annotations that can be understood by Kotlin.
Miscellaneous
@VisibleForTesting
: Corresponds to Guava's@VisibleForTesting
annotation.
Sample Projects
Sample projects for this library can be found in sample
subdirectory:
-
pl.tlinkowski.annotation.sample.api
: sample Java API annotated with@NonNullPackage
and@ReadOnly
-
pl.tlinkowski.annotation.sample.usage.java
: usage of the above API (both correct and incorrect, the latter resulting in warnings from IntelliJ IDEA) -
pl.tlinkowski.annotation.sample.usage.kotlin
: usage of the above API (both correct and incorrect, the latter resulting in errors from Kotlin compiler)
Requirements
Usage: JDK 8+.
Building: Gradle 5+, JDK 11+.
About the Author
See my webpage (tlinkowski.pl) or find me on Twitter (@t_linkowski).