Могу ли я клонировать объект, если у меня есть доступ только к его интерфейсу и он не сериализуем?

#java

#java

Вопрос:

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

Могу ли я по-прежнему клонировать объект? Я имею в виду, могу ли я сделать что-то вроде:

 public void copyMyObject(MyObject myObject){
    this.copyOfMyObject = ...//? can I make a deep copy?

}
 

Думаю, нет … но, возможно, я что-то упускаю.

Комментарии:

1. Возможно, вы сможете обойти это, проверив различные интерфейсы сериализации. Но хороший ли это код? Нет, это, конечно, не так. Если ваш код должен иметь возможность копировать объект, он должен быть снабжен всей необходимой информацией для этого. Все остальное — плохой дизайн, и его следует избегать любой ценой.

2. да, на самом деле речь идет не о хорошем / плохом. Речь идет о моем понимании Java. Что я делаю, если мне нужно сохранить состояние этого объекта? Это неразрешимая проблема, если я не могу ее клонировать? Итак, должен ли я предоставить или попросить возможность клонирования?

Ответ №1:

Хорошо… это зависит.

Вы можете сериализовать объект, если фактический класс объекта реализует Serializable … и остальные 1. Фактический тип может отличаться от (статического) типа переменной, из которой вы получаете ссылку на объект.

Но если нет, то вы ничего не упускаете. Глубокое копирование объекта, который не реализует свои собственные методы глубокого копирования, геттеры и сеттеры или какую-либо форму сериализации, потребует крайне неприятного кодирования 2.

Вам лучше спроектировать свои классы так, чтобы их можно было сериализовать / клонировать. Или, чтобы вам не нужно было их клонировать.

Обратите внимание, что есть несколько классов Java, которые было бы невозможно правильно клонировать даже «неприятными» средствами. Примеры включают Thread , Socket , Class , ClassLoader и некоторые ключевые awt классы. Итак, если бы ваш (гипотетический) дизайн приложения зависел от (скажем) возможности клонирования запущенного потока, этот дизайн не был бы осуществимым.


1 — Поля экземпляра, которые не transient являются и не null должны быть сериализуемыми. И так далее.
2 — Например, вы могли бы использовать отражение, нарушающее абстракцию, и использовать Unsafe для репликации того, что делает реализация сериализации объекта под капотом… без Serializable проверки типа. Хотя это плохая идея.