2

I'm trying to annotate the method java.util.List.toArray using Eclipse's external annotations, but I'm not sure how to annotate the return type. If my List has the following signature:

@NonNull List<@NonNull Element>

List.toArray should return:

@NonNull Element @NonNull[]

If, however, the list can contain nullable elements:

@NonNull List<@Nullable Element>

List.toArray should return an array with nullable elements, too:

@NonNull Element @Nullable[]

I'm using Eclipse Neon, is this even possible? The Eclipse Neon New and Noteworthy page seems to provide an example for List.get() and suggests that I should ommit the nullity for the value, but that doesn't seem to work for arrays? Here is the external annotation definition I'm using:

class java/util/List
toArray
 <T:Ljava/lang/Object;>([TT;)[TT;
 <T:Ljava/lang/Object;>([T1T;)[T1T;

But this doesn't work:

    @NonNull
    List<@NonNull String> collect = // works
    @NonNull
    String @NonNull [] array = collect.toArray(new String[0]);

collect.toArray is marked as error:

Null type safety (type annotations): The expression of type 'String[]' needs unchecked conversion to conform to '@NonNull String []'

How can I fix this? Does this even work with Eclipse Neon, yet?

Nathan
  • 8,093
  • 8
  • 50
  • 76
looper
  • 1,929
  • 23
  • 42
  • `toArray` return the same type you pass as parameter, and `new String[0]` has no `@NonNull` annotation. But note that there is no connection between the array type and the `Collection`’s element type, e.g. you could even write `String[] array = collect.toArray(new String[0]);` when `collect` has the type `List`. It would even work if the `List` is empty. Regarding the nullness, it would require special treatment by the checker, but note that the contract is special: if the array is bigger than the collection’s size, the array element following the last element will be `null`ed out. – Holger Oct 19 '16 at 17:34

1 Answers1

1

I found this advice and followed it in Eclipse 2020-03: I placed the cursor between the "T" and the "[]" of the return type, opened the context menu, and selected "Annotate as Not Null". This had the desired effect, as if the method was declared

@NonNull <T> T[] toArray(T[] a)

The generated List.eea file looks like this:

class java/util/List
toArray
 <T:Ljava/lang/Object;>([TT;)[TT;
 <T:Ljava/lang/Object;>([TT;)[1TT;
Martin Rust
  • 91
  • 1
  • 4