Testing / JUnit6 Interview Questions
What are JSpecify nullability annotations in JUnit 6 and why do they matter?
JUnit 6 adds JSpecify nullability annotations (@Nullable, @NonNull, @NullMarked) to its entire public API. This is a significant improvement for static analysis, IDE tooling, and Kotlin interoperability.
| Annotation | Meaning | Where applied |
|---|---|---|
| @NonNull | The annotated element is never null | Method parameters and return types that must not be null |
| @Nullable | The annotated element may be null | Parameters or return types that can legitimately be null |
| @NullMarked | All unannotated types in this scope are treated as non-null by default | Applied at package, class, or module level to reduce annotation clutter |
// JUnit 6 API example with JSpecify annotations: // (simplified from actual JUnit 6 source) @NullMarked // all unannotated types are non-null by default public class Assertions { // @Nullable return type: assertNull can only be called with a // value the compiler considers potentially null public static void assertNull(@Nullable Object actual) { ... } // Non-null enforced: message MUST be non-null public static void assertEquals( Object expected, Object actual, String message // @NonNull from @NullMarked ) { ... } } // Kotlin benefit: Kotlin compiler recognises JSpecify annotations // Smart casts work after assertNotNull(): val result: String? = getValue() assertNotNull(result) // Kotlin sees NonNull contract println(result.length) // No !! needed -- compiler knows non-null // JUnit 5 problem: assertNotNull(result) // JUnit 5 had no contract println(result!!.length) // !! still needed -- compiler didnt know
More Related questions...