Найти тему

Копаю каверзные вопросы по Java уровня advanced.

Интересные вещи иногда находятся.
Есть, например, интерфейс Serializable (в экосистеме Java нет такого naming convention, чтоб интерфейсы в обязательном порядке с буквы I именовать). Это интерфейс-маркер – то есть, в нём нет никаких методов, он служит только чтоб дать знать JVM о чём-то. В данном случае – о том, что класс можно сериализовывать своими средствами. Это удобно – не нужно писать сериализацию и десериализацию самостоятельно.
Объявляем класс Foo, говорим, что он implements Serializable, и он спокойно сериализуется и десериализуется.
Океечки.
Объявляем класс Bar, не пишем ему Serializable. Объявляем в Foo поле типа Bar.
Предсказуемо, при попытке прогнать через сериализацию/десериализацию вываливается NotSerializableException.
Океечки.
Убираем из Foo поле типа Bar, вместо этого берём и наследуем Foo от этого самого Bar.
Теперь сериализация и десериализация работают. Потому как сам-то Foo у нас Serializable.
Но есть нюанс.
Объявляем в классе Bar поле public String s и конструктор без параметров, в котором s присваиваем значение "alpha".
Создаём объект класса Foo, присваиваем этому самому s значение "bravo", сериализуем, десериализуем. У десериализованного объекта s имеет значение "alpha". То есть, если сериализуемый средствами JVM класс наследуется от несериализуемого, то сам-то этот класс сериализуется, но унаследованные от несериализуемого класса поля не сериализуются (хотя исключения и не кинет).
Океечки.
Добавляем к Bar, что он implements Serializable. Теперь после сериализации у десериализованного объекта поле s будет значение "bravo", то есть теперь унаследованные поля тоже сериализуются.
1 минута