我有一些代码需要发送对象的副本。此要求是因为调用的服务(运行时库)会修改发送的对象。该对象还需要公开 setter ,以防下面的 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);
}
所以该方法的第一行是我陷入困境的地方。它是通用类型,因此我无法显式调用某些克隆实用程序,例如 Jackson 或类似的实用程序。
所以我想我只需将 T extends Cloneable
添加到该方法中...但我打开了 Cloneable
超出禁忌的蠕虫 jar ( https://www.artima.com/intv/bloch13.html ) 。我还读到,复制构造函数可能是处理这个问题的最佳方法...但是,我不确定如何使用泛型来表示这一点。
所以我的想法是提供一个接口(interface)Copyable
,它可以完成您期望Cloneable
做的事情:公开一个方法,copy()
这将创建该类的一个新实例。
这是否是一种可行的方法?
最佳答案
要解决您的问题,您需要以多态方式创建 dataObject
的副本,如下所示:
T cloneOfDataObject = dataObject.clone();
问题是 Cloneable
没有 clone()
方法,因此上面的代码无法编译。
鉴于这个前提,创建您自己的 Copyable
接口(interface)来定义 clone()
方法确实有意义,这样您就可以利用已经实现的 clone( )
数据对象的类上的方法(如果存在)。为了获得最大的效率,这个接口(interface)也需要是通用的:
interface Copyable<T> {
public T clone();
}
和类型绑定(bind):
public class DangerousCallWrapper<T extends Copyable<T>>
implements DangerousCaller<T> {
关于java - 创建 `Copyable` 类型接口(interface)而不是使用 `Cloneable` 是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56814316/