module-info.java
)The purpose of this library is to provide a couple of basic annotations related to the following concepts:
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-null String
String?
(Kotlin) / @NullOr String
(Java) → null
or String
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.
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 of T
MutableList<T>
(Kotlin)
/ @Mutable List<T>
(Java) → mutable list of T
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.
@VisibleForTesting
:
Corresponds to Guava's
@VisibleForTesting
annotation.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)
Usage: JDK 8+.
Building: Gradle 5+, JDK 11+.
See my webpage (tlinkowski.pl) or find me on Twitter (@t_linkowski).