what is the @RecentlyNonNull annotation?

JavaAndroid

Java Problem Overview


I am doing a code inspection on Android Studio and the following warning pops up

Probable bugs
@NotNull/@Nullable problems 
Not annotated method overrides method annotated with @RecentlyNonNull

for the following codes

@Override
public String toString() {
    return title;
}

enter image description here

I've seen @NonNull annotation before, which means that the return can never be a null. but what is @RecentlyNonNull? when do I use it?

googling leads me to https://android.googlesource.com/platform/tools/metalava/+/fcb3d99ad3fe17a266d066b28ceb6c526f7aa415/stub-annotations/src/main/java/android/support/annotation/RecentlyNonNull.java

which does not provide any explanations.

The lint recomendation is to add that annotation in, but what does it do?

enter image description here

Java Solutions


Solution 1 - Java

TL-DR
Consider @RecentlyNonNull as a @NonNull constraint and respect it in the same way in your code because @RecentlyNonNull is under the hood a @NonNull constraint.

Which means in the actual question, the OP should annotate the overrided method with @NonNull to be compliant with the @NonNull (transformed at build time into @RecentlyNonNull) defined in the super class.


The @RecentlyNonNull annotation doesn't make part of the SDK javadoc API.
It is not present in the support subpackage because it is not designed to be present in the source code. Instead, that is computed at build time and replace @NonNull if it is considered as "recent" in the stub source files.

As that is an internal processing, I don't have a simple and straight answer to your question but I may give you some pointers to understand better this annotation and its origin.

1) @RecentlyNonNull or @RecentlyNullable : annotations generated only in the stub source file.

In Android, the generated stub files and the generated documentation stubs don't bring the same level of information : @RecentlyNonNull or @RecentlyNullable may appear in stub files but never in documentation stubs that stick to stub files only.

You can find the information in the Options class source code :

"$ARG_DOC_STUBS ", "Generate documentation stub source files for the API. Documentation stub " +
"files are similar to regular stub files, but there are some differences. For example, in " +
"the stub files, we'll use special annotations like @RecentlyNonNull instead of @NonNull to " +
"indicate that an element is recently marked as non null, whereas in the documentation stubs we'll " +
"just list this as @NonNull...

This googlesource document confirms that :

> There are some annotations here which are not in the support library, > such as @RecentlyNullable and @RecentlyNonNull. These are used > only in the stubs to automatically mark code as recently annotated > with null/non-null. We do not want these annotations in the source > code; the recent-ness is computed at build time and injected into the > stubs in place of the normal null annotations.

2) Annotations introduced for code linters and IDE warning/errors.

According to this blog these annotations take their origin from the Kotlin support and allows the compiler/linter to apply a severity level of the non null violation according to how recent is the non null constraint (recent : warning compilation, not recent : error compilation) :

> Normally, nullability contract violations in Kotlin result in > compilation errors. But to ensure the newly annotated APIs are > compatible with your existing code, we are using an internal mechanism > provided by the Kotlin compiler team to mark the APIs as recently > annotated. Recently annotated APIs will result only in warnings > instead of errors from the Kotlin compiler. You will need to use > Kotlin 1.2.60 or later. > > Our plan is to have newly added nullability annotations produce > warnings only, and increase the severity level to errors starting in > the following year's Android SDK. The goal is to provide you with > sufficient time to update your code.

Solution 2 - Java

Obviously it implies non-nullability, but I'm guessing the "recently" part implies that it just recently became annotated as such.

For example Object.toString did not use to be @NonNull, so now that it is, we say it is @RecentlyNonNull and whoever overrides it should be @NonNull as well. If you look at the source code the annotation is not present. This means some magic is behind this particular method being not nullable, and that is why is it marked as "recent".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAngel KohView Question on Stackoverflow
Solution 1 - JavadavidxxxView Answer on Stackoverflow
Solution 2 - JavaSMMHView Answer on Stackoverflow