У меня есть фрагмент кода, требующий отправки копии объекта. Это требование связано с тем, что вызываемая служба (библиотека времени выполнения) изменяет отправленный объект.Этот объект также должен предоставлять сеттеры на случай, если приведенный ниже метод doThing
должен установить любое поле в классе ImportantObj
.Эта реализация ожидает изменений, но не имеет разумных ожиданий, которые будут изменены в ближайшем будущем.Мой обходной путь - предоставить класс, который делает следующее:
public class DangerousCallWrapper<T> implements DangerousCaller<T> {
public T doThing(T dataObject) {
T cloneOfDataObject = #Clone of dataObject
// This service modifies the cloneOfDataObject... dangerous!
Optional<T> result = service.doThing(cloneOfDataObject);
return result.orElseThrow(() -> new RuntimeException("No data object returned);
}
}
public interface DangerousCaller<T> {
/**
* Performs the functionality of the DangerousService
*/
public T doThing(T);
}
public DangerousService<T> {
public T doThing(T data) {
data.importantField = null;
data.thing = "Done!";
return data;
}
}
public static void main() {
DangerousService service = new DangerousService<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would fail this check
assertNotNull(important.importantField);
DangerousCallWrapper wrapper = new DangerousCallWrapper<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would not fail this check
assertNotNull(important.importantField);
}
Итак, первая строка этого метода - это то, где я застрял.Это универсальный тип, поэтому я не могу явно вызвать какую-либо утилиту для клонирования, такую как Джексон или аналогичную.
Так что я подумал, что просто добавлю T extends Cloneable
к методу ... но я открыл банку с червями, что Cloneable
вне табу (https://www.artima.com/intv/bloch13.html). Я также читал, что конструкторы копированиявероятно, это лучший способ справиться с этим ... Однако я не уверен, как обозначить это с помощью обобщений.
Поэтому я подумал о том, чтобы предоставить интерфейс Copyable
, который будет делать то, что вы ожидаете Cloneable
to do: выставить метод copy()
, который создаст новый экземпляр класса.
Это жизнеспособный подход?