← Назад к вопросам

Как проверить, что передаваемый в метод аргумент не равен null

1.0 Junior🔥 291 комментариев
#ООП#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как проверить аргумент на null в Java?

Этот вопрос касается базовой защиты методов от некорректных входных данных. Существует несколько подходов, каждый с собственными плюсами и минусами.

1. Базовая проверка с if

public void processUser(User user) {
    if (user == null) {
        throw new IllegalArgumentException("User cannot be null");
    }
    
    // Дальше работаем с user
    System.out.println(user.getName());
}

// Использование
User user = new User("John", 30);
processUser(user);          // OK
processUser(null);          // IllegalArgumentException

Плюсы:

  • Простто и понятно
  • Явная проверка
  • Любое исключение можно выбросить

Минусы:

  • Код повторяется
  • Нужно писать в каждом методе

2. Objects.requireNonNull() (рекомендуется)

Автоматизированный способ из java.util:

import java.util.Objects;

public void processUser(User user) {
    // Проверяет, выбрасывает NullPointerException если null
    Objects.requireNonNull(user);
    
    // Или с custom сообщением
    Objects.requireNonNull(user, "User cannot be null");
    
    // Или с supplier для ленивого вычисления сообщения
    Objects.requireNonNull(user, () -> "User is null at " + System.currentTimeMillis());
    
    System.out.println(user.getName());
}

// Использование
processUser(null);  // NullPointerException: User cannot be null

Плюсы:

  • Стандартный способ
  • Лаконичный код
  • Встроенная поддержка в Java
  • Возвращает значение (может присвоить переменной)

Минусы:

  • Всегда выбрасывает NullPointerException
  • Нельзя выбросить другое исключение

3. @NonNull аннотация (инструменты, не runtime)

JetBrains @NotNull или javax.annotation:

import org.jetbrains.annotations.NotNull;

public void processUser(@NotNull User user) {
    // Аннотация сообщает IDE и статическим анализаторам
    // что user не может быть null
    
    System.out.println(user.getName());  // IDE не подчеркивает
}

// Использование
User user = null;
processUser(user);  // IDE предупреждает: "Passing null to method marked @NotNull"

Плюсы:

  • IDE дает подсказки
  • Статический анализ (IntelliJ может найти баги)
  • Не требует runtime проверок

Минусы:

  • Только IDE поддержка, не runtime
  • Нужна конфигурация IDE
  • Может игнорироваться

4. Apache Commons Lang (для legacy кода)

import org.apache.commons.lang3.Validate;

public void processUser(User user) {
    // Похожа на Objects.requireNonNull
    Validate.notNull(user, "User must not be null");
    
    // Или notEmpty для коллекций
    Validate.notEmpty(users, "Users list must not be empty");
    
    // Или notBlank для строк
    Validate.notBlank(email, "Email must not be blank");
}

5. Spring Assert (для Spring приложений)

import org.springframework.util.Assert;

public void processUser(User user) {
    // Выбрасывает IllegalArgumentException
    Assert.notNull(user, "User cannot be null");
    
    // Или для коллекций
    Assert.notEmpty(users, "Users list cannot be empty");
    
    // Или для строк
    Assert.hasText(email, "Email must have text");
}

6. Google Preconditions (Guava библиотека)

import com.google.common.base.Preconditions;

public void processUser(User user) {
    // Выбрасывает NullPointerException
    Preconditions.checkNotNull(user, "User is null");
    
    // Или с форматированием
    Preconditions.checkNotNull(user, "User %s is invalid", userId);
    
    // Для условий
    Preconditions.checkArgument(user.getAge() > 0, "Age must be positive");
}

7. Optional (современный подход)

Для случаев, когда null допустим:

import java.util.Optional;

public void processUser(Optional<User> userOpt) {
    // Явно показываем, что user может быть пустой
    User user = userOpt.orElseThrow(
        () -> new IllegalArgumentException("User cannot be null")
    );
    
    System.out.println(user.getName());
}

// Использование
processUser(Optional.of(new User("John", 30)));  // OK
processUser(Optional.empty());                    // Исключение

Плюсы:

  • Явно указывает, что значение может быть отсутствующим
  • Функциональный подход
  • Цепочные операции

Минусы:

  • Более многословно
  • Может быть overkill для простых проверок

8. Комбинированная проверка нескольких параметров

public void createOrder(
    User user,
    List<Product> products,
    String address) {
    
    Objects.requireNonNull(user, "User cannot be null");
    Objects.requireNonNull(products, "Products cannot be null");
    Objects.requireNonNull(address, "Address cannot be null");
    
    if (products.isEmpty()) {
        throw new IllegalArgumentException("Order must have at least one product");
    }
    
    if (address.isBlank()) {
        throw new IllegalArgumentException("Address cannot be blank");
    }
    
    // Дальнейшая логика
}

Или более компактно:

public void createOrder(
    User user,
    List<Product> products,
    String address) {
    
    Objects.requireNonNull(user, "User required");
    Objects.requireNonNull(products, "Products required");
    Objects.requireNonNull(address, "Address required");
    assert !products.isEmpty() : "Order must have products";
    assert !address.isBlank() : "Address cannot be blank";
    
    // Логика
}

9. Валидация с Bean Validation (Hibernate Validator)

Для Spring/Jakarta приложений:

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotBlank;

public class UserRequest {
    @NotNull(message = "User name cannot be null")
    private String name;
    
    @NotEmpty(message = "Email cannot be empty")
    private String email;
    
    @NotBlank(message = "Address cannot be blank")
    private String address;
}

public void createUser(@Valid UserRequest request) {
    // Spring автоматически валидирует
    // Если есть null/empty поля → MethodArgumentNotValidException
    
    User user = new User(request.getName(), request.getEmail());
    userRepository.save(user);
}

Практические рекомендации

Для простого случая:

// ✓ Best practice
public void processUser(User user) {
    Objects.requireNonNull(user, "User cannot be null");
    // ...
}

Для Spring приложения:

// ✓ Используй Bean Validation
@PostMapping("/users")
public void createUser(@Valid @RequestBody UserRequest request) {
    // Spring автоматически проверит null/empty поля
}

Для сложной логики:

// ✓ Используй Optional
public Optional<User> findUser(Long id) {
    return userRepository.findById(id);
}

public void processUser(Long userId) {
    User user = findUser(userId)
        .orElseThrow(() -> new UserNotFoundException(userId));
    
    // Работаем с user
}

Для инжиниринга performance-critical кода:

// ✓ Используй assert (отключается в production)
public void criticalOperation(Data data) {
    assert data != null : "Data cannot be null";  // Только в development
    
    // Production код без этой проверки
}

// Запуск с enabled assertions:
// java -ea MyApp

Типичные ошибки

❌ Неправильно: забыть проверить

public void processUser(User user) {
    System.out.println(user.getName());  // NPE если user == null!
}

❌ Неправильно: вложенная проверка

public void processUser(User user) {
    if (user != null && user.getName() != null) {
        System.out.println(user.getName());  // Слишком многословно
    }
}

✓ Правильно:

public void processUser(User user) {
    Objects.requireNonNull(user, "User cannot be null");
    Objects.requireNonNull(user.getName(), "User name cannot be null");
    System.out.println(user.getName());
}

Вывод

Выбор метода зависит от контекста:

  1. Простые методыObjects.requireNonNull()
  2. Spring приложения → Bean Validation @Valid
  3. Legacy кодValidate.notNull() из Apache Commons
  4. Когда null допустимOptional<T>
  5. IDE подсказки@NotNull аннотация
  6. Performance criticalassert (отключаемо)

Главное правило: ВСЕГДА проверяй null перед использованием!

Как проверить, что передаваемый в метод аргумент не равен null | PrepBro