Documentation

Documentation versions (currently viewingVaadin 24.4 (pre))

Type Nullability

Understanding optional nullable types.

Types that are set as non_nullable are in essence required. Whereas types that are set as nullable are not required and thereby optional. By default, types are mapped and generated using the Java rules:

  • Any primitive type, such as int, is non-nullable.

  • Any reference type, such as String or Integer, is nullable.

  • A collection accepts null, unless the collection item type is primitive.

  • A map accepts null, unless the collection item type is primitive.

Any of these nullable types can be made non-nullable by applying a @Nonnull annotation.

You can use any annotation that has the name nonnull (case-insensitive). Below are examples of this:

  • jakarta.annotation.Nonnull;

  • edu.umd.cs.findbugs.annotations.NonNull;

  • lombok.NonNull;

  • android.support.annotation.NonNull;

  • org.eclipse.jdt.annotation.NonNull; or

  • any other annotation (including custom) that has the name nonnull (case-insensitive).

Endpoint Functions

For an endpoint function, nullable elements are as follows: Function Parameter Type or Function Return Type.

For Function Parameter Types, arguments cannot be omitted, even when the parameter types are nullable. To receive a null parameter value in Java, send an undefined argument in the endpoint function call.

@Endpoint
class PersonEndpoint {
    // Person must have at least the first and last name.
    public void setFullName(@Nonnull String firstName, @Nonnull String lastName, String middleName) {
        // omitted code
    }

    // Full name must exist.
    @Nonnull
    public String getFullName() {
        // omitted code
    }

    // Person should have no connections with other people. If they have,
    // the connection cannot be null.
    public Map<String, @Nonnull String> getConnections() {
        // omitted code
    }
}
export async function setName(
  firstName: string,
  lastName: string,
  middleName: string | undefined
) {
  return client.call('PersonEndpoint', 'setFullName', {firstName, lastName, middleName});
}

export async function getFullName(): Promise<string> {
  return client.call('PersonEndpoint', 'getFullName');
}

export async function getConnections(): Promise<Record<string, string> | undefined> {
  return client.call('PersonEndpoint', 'getConnections');
}

Data Class Properties

Properties of data classes are nullable. Unlike the function parameters, all nullable properties can be omitted.

public class MyBean {
    private long id;
    @Nonnull
    private String value;
    private String description;
    private Map<String, String> map;
    @Nonnull
    private List<String> list;
}
export default interface MyBean {
  id: number;
  value: string;
  description?: string;
  map?: Record<string, string | undefined>;
  list: Array<string | undefined>;
}

Collection Item Types

The collection item type is nullable.

public class MyBean {
    private List<String> list;
    private List<@Nonnull String> nonNullableList;
    private Map<String, String> map;
    private Map<String, @Nonnull String> nonNullableMap;
}
export default interface MyBean {
  list?: Array<string | undefined>;
  nonNullableList?: Array<string>;
  map?: Record<string, string | undefined>;
  nonNullableMap?: Record<string, string>;
}

@NonNullApi

Along with @Nonnull annotations, you could also use package-level @NonNullApi annotations. It would make all of the nullable types in a package non-nullable by default. All nested types — List and Map items, etc. — are also affected.

By default, the following annotation is supported: org.springframework.lang.NonNullApi.

To make any type nullable, you must add @Nullable annotation to it.

@NonNullApi
package com.example.application;
public class MyBean {
    public List<String> list;
    public Map<String, Integer> map;
    @Nullable
    public String nullable;
}
export default interface MyBean {
  list: Array<string>;
  map: Record<string, number>;
  nullable?: string;
}