Noo*_*tor 3 java copy object java-8
所以我有,我需要一个用例复制一个object
的class
ES(类可以根据在工厂输入类型而变化.
这是我想要做的样本
public interface DataUtil {
// the main wrapper
static Object copyObject(Object payload){
if(payload instanceof Human))
return copyEntry((Human) payload);
if(payload instanceof Car))
return copyEntry((Car) payload);
if(payload instanceof Planet))
return copyEntry((Planet) payload);
return payload;
}
static Human copyEntry(Human human) {
return Human.builder()
.name(human.getName())
.age(human.getAge())
.build();
}
static Car copyEntry(Car car) {
return Car.builder()
.model(car.getModel())
.brand(car.getBrand())
.build();
}
static Planet copyEntry(Planet planet) {
// return builder like previous
}
}
Run Code Online (Sandbox Code Playgroud)
如果你看一下copyObject
函数,它会按预期完成工作,但是他的问题是返回类型.目前,为了使自己兼容,它返回一个,Object
但我宁愿返回它特定的类对象(例如Human
或说Car
)
有没有办法通过Generics(使用<T>
)完成这项工作?或者这首先是一个糟糕的做法?
有没有办法通过Generics(使用)完成这项工作?或者这首先是一个糟糕的做法?
这是一个糟糕的方法,因为您收到参数a Object
.
你不能从中推断具体类型:而instanceof
你使用的是.这不是一个好方法.
这里有两个想法(足够相关)
1)介绍可复制的界面
您可以引入一个接口,您要复制的对象的类实现:
public interface Copyable<T> {
T copy(T t);
}
Run Code Online (Sandbox Code Playgroud)
可以实施,如:
public class Human implements Copyable<Human> {
@Override
public Human copy(Human t) {
return Human.builder()
.name(human.getName())
.age(human.getAge())
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
所以一般的copy()方法可能如下所示:
// the main wrapper
static <T extends Copyable<T>> T copyObject(T payload) {
return payload.copy(payload);
}
Run Code Online (Sandbox Code Playgroud)
你可以用这种方式使用它:
Human human = new Human();
// set some fields ...
Human copiedHuman = copyObject(human); // compile
Car copiedCar = copyObject(human); // doesn't compile
Run Code Online (Sandbox Code Playgroud)
2)使用访客模式
作为替代方案,它也是访问者模式的一个好例子:您希望根据参数的具体类型应用处理.
它允许将复制操作组合在一起,就像在实际代码中一样.
一般copyObject()
方法可以依赖于CopyVisitor
根据参数的具体类型进行复制:
@SuppressWarnings("unchecked")
static <T extends Visited> T copyObject(T payload) {
CopyVisitor visitor = new CopyVisitor();
payload.accept(visitor);
return (T) visitor.getCopy();
}
Run Code Online (Sandbox Code Playgroud)
在哪里CopyVisitor
实现经典Visitor
界面:
public interface Visitor {
void visitHuman(Human human);
void visitCar(Car car);
void visitPlanet(Planet planet);
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式 :
public class CopyVisitor implements Visitor {
private Visited copy;
@Override
public void visitHuman(Human human) {
copy = Human.builder()
.name(human.getName())
.age(human.getAge())
.build();
}
@Override
public void visitCar(Car car) {
copy = Car.builder()
.model(car.getModel())
.brand(car.getBrand())
.build();
}
@Override
public void visitPlanet(Planet planet) {
//...
}
public Visited getCopy() {
return copy;
}
}
Run Code Online (Sandbox Code Playgroud)
被访问的类(Car,Human,Plan)将实现一个特定的接口来"接受"访问者:
public interface Visited {
void accept(Visitor visitor);
}
Run Code Online (Sandbox Code Playgroud)
如 :
public class Human implements Visited {
@Override
public void accept(Visitor visitor) {
visitor.visitHuman(this);
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可以用copy()
这种方式使用这个方法:
Human human = new Human();
// set some fields ...
Human copiedHuman = copyObject(human); // compile
Car copiedCar = copyObject(human); // doesn't compile
Run Code Online (Sandbox Code Playgroud)