undefined

Интерфейсы-маркеры, глубокое клонирование

Java Multithreading
4 уровень , 1 лекция
Открыта
Интерфейсы-маркеры, глубокое клонирование - 1

— Привет, Амиго!

— Привет, Билаабо!

— Сегодня я расскажу тебе про интерфейсы-маркеры.

Интерфейсы-маркеры – это интерфейсы, которые не содержат методов. Когда класс наследуется от такого интерфейса, то говорят, что он им помечен.

Примеры таких интерфейсов: Cloneable, Serializable, Remote.

Интерфейс Serializable используется, чтобы помечать классы, которые поддерживают сериализацию — как доказательство того, что объекты класса можно автоматически сериализовать и десериализовать.

Интерфейс Remote используется, чтобы обозначать объекты, которые поддерживают удаленный вызов – вызов из другой Java-машины и/или другого компьютера.

Интерфейс Cloneable используется, чтобы помечать классы, которые поддерживают клонирование.

Кстати, о клонировании.

Клонирование делится на два типа – обычное клонирование и глубокое клонирование.

Обычное клонирование – это когда создается дубликат только указанного объекта, без его внутренних объектов.

Глубокое клонирование – это когда создается дубликат объекта, объектов, на которые он ссылается, объектов, на которые ссылаются они и т.д.

Есть очень хороший способ выполнить качественное глубокое клонирование.

Этот способ подходит, даже если разработчики классов забыли пометить его интерфейсом Cloneable. Достаточно, чтобы объекты были сериализуемыми.

Вот что можно сделать:

1) Создать буфер (массив байт) в памяти.

2) Сериализовать в него нужный объект с подобъектами.

3) Десериализовать из буфера копию сохраненной в него группы объектов.

Код
BigObject objectOriginal = new BigObject();

ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(writeBuffer);
outputStream.writeObject(objectOriginal);
outputStream.close();

byte[] buffer = writeBuffer.toByteArray();
ByteArrayInputStream readBuffer = new ByteArrayInputStream(buffer);
ObjectInputStream inputStream = new ObjectInputStream(readBuffer);
BigObject objectCopy = (BigObject)inputStream.readObject();

На первой строчке мы создаем объект objectOriginal, который будем клонировать. Он и все его подобъекты должны поддерживать сериализацию.

На третьей строчке мы создаем ByteArrayOutputStream – массив байт, который будет динамически растягиваться при добавлении к нему новых данных (как ArrayList).

На 4-й строчке мы создаем ObjectOutputStream, который используется для сериализации.

В пятой строчке мы сериализуем объект objectOriginal в массив байт с помощью outputStream и сохраняем его в массив writeBuffer.

На 8-й строчке мы преобразовываем writeBuffer в обычный массив байт. Дальше мы из этого массива будем «читать» наш новый объект.

На 9-й строчке мы оборачиваем buffer в класс ByteArrayInputStream, чтобы из него можно было читать, как из InputStream.

На 10-й строчке передаем объект readBuffer классу ObjectInputStream, для чтения (десериализации) объекта.

На 11-й строчке мы читаем наш объект и преобразуем его к типу BigObject.

Как тебе?

— Красота.

Кстати, когда код раскрашен разными цветами – гораздо легче его понимать.

Комментарии (56)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Flexo 35 уровень, New New York
28 апреля 2021
Краткое содержание: - вот есть такое в джаве - интерфейсы без методов - клонирование бывает глубокое и не очень - а вот так клонировать без реализации Cloneable
Даниил Александрович 31 уровень, Тамбов
3 марта 2021
вот так и появились первые вирусы ;)
Темиргалиев Тимур 33 уровень, Москва
3 ноября 2020
большая статья)
Alexey 36 уровень
30 июля 2020
Интерфейсы-маркеры – это интерфейсы, которые не содержат методов. Да ладно!? 😄
Andrei Sverzh 41 уровень, Минск
10 мая 2020
осталось разобраться с практическим применением данного материала?
Сиявуш 41 уровень, Худжанд Expert
27 января 2020
Повторение - мать учение!
alezalez 35 уровень, Одесса
3 ноября 2019
Всем привет. Не знаю, прав я или ошибаюсь, но у меня сложилось впечатление, что создатели джавараш сознательно делают такие уроки: вначале окунают в непонятку, когда начинаешь гуглить и с трудом проходишь валидацию, а через пару уроков повторно и более детально поясняют материал. Как оказалось для меня - так очень даже неплохо: когда на старые знания повторно приходит структурированный материал, и я повторно его читаю - гораздо лучше приходит понимание (это "раз"), и лучше запоминаются конструкции(это "два").
Самуил Олегович 41 уровень, Киев
11 августа 2019
Вот впервые согласен с Би — красота! Когда код раскрасить разными цветами)))
skybright 41 уровень Expert
1 июля 2019
Кстати, как скопировать код вместе с раскраской? При вставке из буфера в MS Word, если цвет один он переносится, а если много все окрашивается в черный. Поделитесь опытом.
Vadim Krant 27 уровень, Москва
15 мая 2019
Вроде не сложно, взяли разобрали объект со всеми его потрошками на байты, затем эти байты опять через потоки собрали обратно в объект. Надо будет попробовать в одной из предыдущих задач, где надо было убедиться в том, что в массив сохранились именно значения переменных, а не ссылки на них. Тоже один из способов решения. Java меня этим путает конечно, а именно тем, что вроде присваиваешь переменной значение второй, а по факту падает ссылка на объект, в итоге меняется оригинал, и меняется та переменная которая получила ссылку на оригинал. Бррр, страшный сон :)