Skip to content

Instantly share code, notes, and snippets.

@Kira9204
Last active September 3, 2024 08:32
Show Gist options
  • Save Kira9204/f55ad07dab58c5fa354e04e04bffe049 to your computer and use it in GitHub Desktop.
Save Kira9204/f55ad07dab58c5fa354e04e04bffe049 to your computer and use it in GitHub Desktop.
@nonull checks Java Jakarta vs Lombok
The `@NotNull` annotation from Jakarta Bean Validation (formerly Javax Validation) and the `@NonNull` annotation from Lombok serve similar but distinct purposes in Java development. Here's a breakdown of the key differences:
### 1. **Purpose and Usage**
- **Jakarta `@NotNull`**:
- **Purpose**: It is a validation constraint used primarily in Java EE or Spring applications to enforce that a particular field or method parameter should not be `null`.
- **Usage**: Typically used on fields, method parameters, or method return types. It is part of the Bean Validation API, which means it's used in contexts where objects are validated, such as when data is being processed by a framework like Spring or Hibernate.
- **Effect**: Triggers a validation error if the annotated element is `null`, often used in combination with a validation framework that checks these constraints at runtime.
```java
import jakarta.validation.constraints.NotNull;
public class User {
@NotNull
private String name;
public void setName(@NotNull String name) {
this.name = name;
}
}
```
- **Lombok `@NonNull`**:
- **Purpose**: It is an annotation provided by Lombok, primarily used to automatically generate null checks in your code. It can be used on fields, method parameters, or methods.
- **Usage**: When used on a method parameter or field, Lombok automatically generates code that checks if the value is `null` and throws a `NullPointerException` if it is.
- **Effect**: The null check happens immediately when the code is executed, typically throwing an exception if the condition is violated. It does not integrate with a validation framework.
```java
import lombok.NonNull;
public class User {
private @NonNull String name;
public void setName(@NonNull String name) {
this.name = name;
}
}
```
### 2. **Integration with Frameworks**
- **Jakarta `@NotNull`**:
- Integrated with validation frameworks (like Hibernate Validator) and used primarily in contexts where objects are being validated, such as forms submitted in a web application, DTOs, or persistence layers.
- Supports additional validation features like custom validation messages.
- **Lombok `@NonNull`**:
- Focused on simplifying boilerplate code by automating null checks. It doesn't integrate with validation frameworks and doesn't provide validation messages.
- Useful primarily for ensuring that methods and constructors are not called with `null` arguments.
### 3. **Runtime Behavior**
- **Jakarta `@NotNull`**:
- The validation occurs typically during a framework-triggered validation process (e.g., when a form is submitted or when an entity is being persisted).
- **Lombok `@NonNull`**:
- The null check occurs immediately at runtime when the method or constructor is invoked.
### 4. **Custom Messages**
- **Jakarta `@NotNull`**:
- Allows specifying custom error messages that can be used when the validation fails.
```java
@NotNull(message = "Name cannot be null")
private String name;
```
- **Lombok `@NonNull`**:
- Does not support custom messages directly since it is designed to generate a `NullPointerException`.
### 5. **Example Scenario**
- **Jakarta `@NotNull`**: Use this when you want to enforce a validation rule across a system, especially in environments where validation frameworks are used (e.g., ensuring a form field is not empty in a web application).
- **Lombok `@NonNull`**: Use this when you want to ensure that your method or constructor does not receive `null` arguments, and you want to avoid writing repetitive null-checking code.
### Summary
- **Jakarta `@NotNull`**: Validation constraint used in frameworks, part of the Bean Validation API.
- **Lombok `@NonNull`**: Annotation to automatically generate null checks in code, simplifying boilerplate but not part of a validation framework.
Lombok example:
In Java, records are a special kind of class that automatically provides implementations for various methods like `equals()`, `hashCode()`, and `toString()`, as well as a compact constructor that initializes the record's fields. When you use the Lombok `@NonNull` annotation on a record field, Lombok behaves in a specific way:
### Behavior of `@NonNull` in a Record
1. **Null Check in the Compact Constructor**:
- When you place `@NonNull` on a record field, Lombok automatically adds a null check in the record's compact constructor. If someone attempts to create an instance of the record with a `null` value for that field, a `NullPointerException` will be thrown.
```java
import lombok.NonNull;
public record Person(@NonNull String name, int age) {
}
```
In this example, if someone tries to instantiate `Person` with a `null` name:
```java
Person p = new Person(null, 30); // Throws NullPointerException
```
Lombok will generate a constructor that includes the following logic:
```java
public Person(String name, int age) {
if (name == null) {
throw new NullPointerException("name is marked non-null but is null");
}
this.name = name;
this.age = age;
}
```
2. **No Impact on Other Generated Methods**:
- The `@NonNull` annotation only affects the constructor. It does not change the behavior of other generated methods like `equals()`, `hashCode()`, or `toString()`. These methods will still behave as they would in any standard Java record.
3. **Error Message**:
- The error message generated by the `NullPointerException` will include the name of the field that was marked as `@NonNull` and was found to be `null`.
### Summary
Using Lombok's `@NonNull` on a record field is primarily for ensuring that the field is not `null` when a new record instance is created. Lombok inserts a null check in the record's compact constructor, ensuring that if a `null` value is passed, a `NullPointerException` is thrown immediately. This helps to catch potential errors early in the object's lifecycle.
In short, adding `@NonNull` to a record field is an effective way to enforce non-null constraints on record components.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment