import withTypeUse.NotNull; import withTypeUse.Nullable; interface Foo { @Nullable Object @NotNull [] getNotNullArrayOfNullableObjects(); @NotNull Object @Nullable [] getNullableArrayOfNotNullObjects(); } class FooImpl implements Foo { @Override public @Nullable Object @NotNull [] getNotNullArrayOfNullableObjects() { return null; } @Override public @NotNull Object @Nullable [] getNullableArrayOfNotNullObjects() { if (Math.random() > 0.5) { return null; } else if (Math.random() > 0.5) { @NotNull Object @Nullable [] arr1 = new Object[]{null, new Object(), Math.random() > 0.5 ? new Object() : null, foo()}; @NotNull Object @Nullable [] arr2 = {null, new Object(), Math.random() > 0.5 ? new Object() : null, foo()}; return new Object[]{null, new Object(), Math.random() > 0.5 ? new Object() : null, foo()}; } return new @NotNull Object @Nullable []{null, new Object(), Math.random() > 0.5 ? new Object() : null, foo()}; } void test() { @NotNull Object @Nullable [] array = getNullableArrayOfNotNullObjects(); assert array != null; array[0] = null; array[1] = Math.random() > 0.5 ? null : "foo"; array[3] = foo(); } native @Nullable Object foo(); }