В чем польза аннотации @Serial от Java 14

В Java 14 представлена ​​новая аннотация @Serial в пакете java.io. Его краткое описание в документации по API:

Указывает, что аннотированное поле или метод является частью механизм сериализации, определенный Спецификацией сериализации объектов Java.

Насколько я понимаю, аннотация используется для проверки во время компиляции (аналогично @Override), чтобы проверить, соответствует ли механизм сериализации методы и поля используются правильно. Чего я не понимаю, влияет ли аннотация на саму десериализацию, если она является частью механизма сериализации? Или это первый шаг к улучшению дизайна функции де/сериализации, как это предлагается в этот комментарий?

Поэтому, если это должна быть полная картина, добавьте их все: @Serializable, @NotSerializable, @Transient и сделайте Serializable устаревшим…

Я смущен его использованием, и я не нашел никакого кода, использующего его. Не могли бы вы предоставить пример кода, выделяющий проблемы, когда аннотация не используется, но должна быть?


person Nikolas Charalambidis    schedule 07.09.2020    source источник


Ответы (2)


Эта аннотация существует исключительно для улучшения проверки типов во время компиляции. В этом смысле она аналогична аннотации @Override, которая существует исключительно для того, чтобы зафиксировать замысел проекта, чтобы у людей и инструментов было больше информации для работы. Аннотация @Override не делает объявление метода переопределением другого, которое обрабатывается языком на основе сравнения имен, сигнатур и доступности между методом и методами в супертипе(ах). Что @Override делает, так это утверждает, что я думаю, что это переопределение, если я ошибаюсь, сообщите мне об ошибке компиляции. И это служит предупреждением для читателей кода, что этот метод не является новым для этого класса.

Поскольку сериализация использует волшебные имена методов и полей (такие методы, как readObject, не являются частью какого-либо интерфейса, они просто волшебным образом получают значение при сериализации), и определение того, работает ли волшебство, сложно (методы должны иметь не только правильное имя и аргументы). , но правильная доступность и статика), легко объявить метод, который, по вашему мнению, предназначен для использования сериализацией, но для которого сериализация не согласуется.

Аннотация @Serial позволяет сделать аналогичное утверждение: вы предполагаете, что это один из тех членов магической сериализации (полей и методов), и если он не соответствует профилю, компилятор должен предупредить вас об ошибке. И это дает аналогичный намек читателям на то, что этот член будет использоваться сериализацией.

Большинство разработчиков, вероятно, не будут беспокоиться об этом для кода приложения и предметной области. Но авторы библиотек могут счесть это полезным как способ более строгой проверки типов и лучшего понимания замысла проекта.

person Brian Goetz    schedule 08.09.2020

Чего я не понимаю, влияет ли аннотация на саму десериализацию

Нет. Его сохранение является «исходным кодом», поэтому он отбрасывается после компиляции. Байт-код не будет содержать его следов. Он никак не может повлиять на поведение во время выполнения (за исключением, возможно, генерации кода во время компиляции, чего не происходит).

Как и @Override, он является необязательным и должен дать некоторую гарантию времени компиляции для проблем, которые в противном случае могли бы не быть обнаружены до времени выполнения.

Например, неправильное написание serialVersionUID:

@Serial
private static final long seralVersionUID = 123L; // compile-time error, should be 'serialVersionUID'

Или неправильный модификатор доступа

// compile-time error, must be private 
@Serial
public void writeObject(java.io.ObjectOutputStream out) throws IOException

По сути, что-то, аннотированное этим, должно точно соответствовать описаниям 7 применимых элементов, упомянутых в JavaDoc (5 методов, 2 поля). Если сигнатура метода не совпадает или модификаторы неверны, вы обнаружите проблему до того, как произойдет сбой сериализации во время выполнения.

person Michael    schedule 07.09.2020
comment
Я вижу смысл, размещение на статическом поле звучит разумно. Но я не понимаю цели аннотации для методов (writeObject, readObject и т.д...). Почему сам интерфейс Serializable не предоставляет методы default начиная с Java 8? - person Nikolas Charalambidis; 07.09.2020
comment
@Nikolas Методы являются частными. Если вы добавили в интерфейс методы по умолчанию, они должны быть общедоступными (как и все методы интерфейса). Существующие классы Serializable сломаются, потому что они попытаются назначить более слабый доступ к этим методам, чем это диктуется интерфейсом. Они не пытаются изменить механизм сериализации. То, что вы предлагаете, является гораздо более сложной задачей. Они просто пытаются добавить некоторые проверки времени компиляции. - person Michael; 07.09.2020