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)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Flexo Уровень 41 New New York
28 апреля 2021
Краткое содержание: - вот есть такое в джаве - интерфейсы без методов - клонирование бывает глубокое и не очень - а вот так клонировать без реализации Cloneable
Даниил Александрович Уровень 35 Тамбов Россия
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 меня этим путает конечно, а именно тем, что вроде присваиваешь переменной значение второй, а по факту падает ссылка на объект, в итоге меняется оригинал, и меняется та переменная которая получила ссылку на оригинал. Бррр, страшный сон :)