Скажем, мне нужен метод для изменения 2 строк (или любого другого неизменяемого класса), я не могу вернуть один объект. Таким образом, я могу передать объект List, String [] или 2 объекта AtomicReference. У каждого из них есть свои недостатки. Списки и массивы не позволяют именовать каждый из параметров, и мы полагаемся на порядок элементов, чтобы гарантировать, что установлены правильные строки. AtomicReference предназначен для атомарных обновлений, поэтому он делает гораздо больше, чем мне нужно. Мне просто нужно что-то вроде этого:

public class Reference <T> {
    private T value;
    public T get() {
        return value;
    }

    public void set(T value) {
        this.value = value;
    }
}

Я бы подумал, что такой класс доступен в какой-нибудь библиотеке Apache или Spring, но я не смог найти ничего подобного. Я бы подумал, что это довольно основная потребность для многих разработчиков, так есть ли это в какой-то сторонней библиотеке, о которой я не знаю?

В основном это относится к случаю 2 или 3 объектов. Когда имеется> 3 неизменяемых объектов, я мог бы создать новый класс только для хранения этих ссылок.

Я также знаю Apache Pair и Triple, но у них та же проблема, что и у List, где я не могу назвать параметры.

0
BGRT 15 Фев 2021 в 16:23

1 ответ

Лучший ответ

Если вы хотите, чтобы "именованные кортежи" были неизменяемыми, наилучшим образом соответствует вашим требованиям класс Java 14+ record. По сути, это легкий класс, который примерно аналогичен C / C ++ struct .... но неизменяемый;

Если вам нужно , чтобы "именованные кортежи" были изменяемыми (или если Java 14+ еще не подходит для вас), есть две альтернативы:

  • Если имена «полей» являются динамическими, вы можете использовать Map. Подойдет любая реализация Map. С этим есть проблемы:

    • Вы должны использовать синтаксис m.get(name) и m.put(name, value).
    • Компилятор не может проверить, что вы используете правильные строки name.
    • Все значения должны быть одного типа или одного базового типа. Если «поля» имеют разные типы, вам нужно будет использовать приведение типов; например от Object до ожидаемого типа.
  • Если имена «полей» статичны (т.е. вы хотите иметь возможность ссылаться на них как на идентификаторы Java, единственной альтернативой является объявление обычного класса. Это может быть «неинкапсулированный» класс, например

    public class Things {
        public Type1 thing1;
        public Type2 thing2;
    }
    

    Поля можно объявить как final, и тогда вам нужно будет объявить конструктор.

    Хотя иметь методы получения, установки и конструктор - это хороший стиль, язык Java не заставляет вас объявлять и / или использовать их. Вам просто нужно понять последствия игнорирования инкапсуляции. (И суметь справиться с обзорами отрицательного кода ...)

Как бы то ни было, вы не можете создать класс библиотеки, в котором имена ваших полей являются обычными параметрами или параметрами типа. (Или, по крайней мере, не таким образом, который может использоваться обычным кодом Java; например, используя x.name или x.getName().) Вот почему вы не можете его найти!

1
Stephen C 17 Фев 2021 в 01:14