Вы здесь:

Что такое неизменяемый объект? Когда вы создаете новое значение для такого объекта, на самом деле создается новый объект, и старый объект остается неизменяемым. Это будет более эффективным по времени и памяти, чем изменение изначального объекта. Это обеспечивает безопасность многопоточного программирования, поскольку неизменяемые объекты могут быть разделены между несколькими потоками без риска изменений и ошибок.

Массивы в Java изменяемый (mutable) тип. Пример решения:

public class ImmutableIntArray {
    private final int[] array;

    public ImmutableIntArray(int[] array) {
        this.array = array.clone();  // clone!!!
    }

    public int[] getValue() {
        return this.clone(); // get clone!!!
    }
}
  • нет сеттеров
  • установка свойств только через конструктор
  • получение свойства через clone

Пример для immutable класса :

public final class Person {
    private final String name;
    private final Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.ssn = age;
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}
  • нет сеттеров
  • свойства задаются только через конструктор
  • свойства final

Пример для immutable класса с коллекциями :

import java.util.List;

public class PizzaDto {

    private final String name;
    private final List<String> ingredients; // final!!!

    public PizzaDto(String name, List<String> ingredients) {
        this.name = name;
        if (ingredients != null) {
            ingredients = List.copyOf(ingredients); // List.copyOf!!!
        }
        this.ingredients = ingredients;
    }

    public String getName() {
        return name;
    }

    public List<String> getIngredients() {
        return ingredients;
    }
}

Проверка:

dto.getIngredients().remove("Sugar"); // вызывает UnsupportedOperationException

либо возвращать clone версию:

public List getNames() {
    return new ArrayList(this.ingredients); // или можно использовать List.copyOf
}

Но внутренние объекты, все равно, нужно держать под контролем. В Spring есть https://learntutorials.net/ru/java/topic/2807/неизменяемые-объекты