Null-Restricted and Nullable Types

Overview of the Proposal

  • JEP introduces three nullness states:
    • T! = explicitly non-null
    • T? = explicitly nullable
    • T (unmarked) = “unspecified; may be null; intent unknown”
  • Goal: express intent in the type system and gradually move toward explicit nullness without breaking existing code.

Nullability Semantics & Design Choices

  • Many like the idea of language-level nullability instead of ad‑hoc annotations or Optional<T>.
  • Unannotated types remaining “maybe-null” are seen as pragmatic but also “the worst default” by some; they fear it encourages continuing to ignore nullability.
  • The ability to override methods with mismatched nullness and to implicitly narrow from T/T? to T! (sometimes throwing NPE at runtime) is widely viewed as a potential footgun.

Runtime vs Compile-time Safety

  • Spec says unaccounted nulls may cause warnings but not compile errors.
    • Supporters: necessary to avoid breaking vast amounts of existing code and libraries.
    • Critics: undermines the point of strong typing; want a way to promote nullness warnings to errors and fear future backwards‑compat constraints.

Backwards Compatibility & Migration

  • Three-way nullness (nonnull/nullable/unspecified) is defended as enabling gradual adoption in large legacy codebases and third‑party libraries.
  • Several people want a future mechanism to mark modules/packages/files as “non-null-by-default” so plain T means T! in that context.
  • Comparisons to C# nullable reference types and Kotlin’s null safety:
    • C#/Kotlin praised for non-null default but criticized for migration pain and mode flags.
    • Java approach seen as slower but safer for old code.

Optional and Value Types

  • Optional<T> is criticized as verbose, unsafe (both Optional and T can be null), and misused; some hope the new system lets the JDK tighten its API.
  • Ties to value classes/Valhalla: non-nullability is seen as crucial to efficient flat value arrays.

Syntax Debate (? and !)

  • Many are comfortable with T?/T! due to precedent in Kotlin, C#, TypeScript, Dart, etc., and value terseness for a very common feature.
  • Others dislike new punctuation, especially reuse of ? alongside wildcard generics, and suggest keywords like nullable/nonnull instead.
  • Some worry about visual noise vs. Java’s already verbose modifier chains.

Broader Reflections on Java

  • Thread frames this as Java “catching up” to ML/Haskell-inspired null‑safety and learning that defaults should be: non-null, immutable, narrow scope.
  • Opinions split between enthusiasm (“finally”) and skepticism (“too late”, “unnecessary complexity”, or “trend-driven”).