我有两个Java对象,如下所示:
class A {
int a;
int b;
}
class B {
int a;
Double b;
}
A objA = new A();
objA.a = 5;
objA.b = 6;
我想将objA克隆到objB中,以便将字段b转换为 从objB访问时加倍,即
objB.b = 6.0
objB.a = 5
注意:
答案 0 :(得分:4)
有frameworks在不同类的对象之间进行映射。查看评论。
如果您不想使用第三方库,则可以编写这些框架所提供内容的过度简化版本。
例如,如果字段的名称相同,并且区别仅在于类型,则可以编写一个method(A a, B b, Rules r)
,它将根据给定的规则将a
映射到b
1 :
public static void copyFromAtoB(A a, B b, Map<String, Function<Object, Object>> rules) throws NoSuchFieldException, IllegalAccessException {
for (Field f : B.class.getDeclaredFields()) {
final String fName = f.getName();
final Object aValue = A.class.getDeclaredField(f.getName()).get(a);
f.set(b, rules.containsKey(fName) ? rules.get(fName).apply(aValue) : aValue);
}
}
规则 2 告诉我们应该对字段应用什么功能才能正确设置值。
如果没有针对字段的规则,则假定类型兼容。
final A a = new A(5, 6);
final B b = new B();
final Map<String, Function<Object, Object>> rules = new HashMap<>();
rules.put("b", i -> Double.valueOf((int)i)); // int -> Double
copyFromAtoB(a, b, rules);
1 是的,这是一种反思方法-可能成本高昂且设计过度,但似乎很灵活。
2 规则定义不明确,因为我们采用Object
并返回Object
(Function<Object, Object>
)。
答案 1 :(得分:2)
如果您按照注释之一的建议尝试使用Apache BeanUtils,则会看到它具有copyProperties
方法,该方法可以在某种程度上转换您的类型。例如,您可以像示例中那样从int自动获取double。但是,如果这些属性确实不兼容,则会出现异常,并且似乎没有办法说您要跳过它。
我的方法是扩展BeanUtilsBean
类并添加类似于copyProperties()
的方法,但有一个额外的参数:一组例外属性:
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import org.apache.commons.beanutils.BeanUtilsBean;
public class MyBeanUtilsBean extends BeanUtilsBean {
public void copyPropertiesExcept(Object dest, Object orig, String... exceptProperties)
throws IllegalAccessException, InvocationTargetException {
PropertyDescriptor[] origDescriptors = getPropertyUtils().getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
if ("class".equals(name)) {
continue; // No point in trying to set an object's class
}
if (Arrays.asList(exceptProperties).contains(name)) {
continue;
}
if (getPropertyUtils().isReadable(orig, name) && getPropertyUtils().isWriteable(dest, name)) {
try {
Object value = getPropertyUtils().getSimpleProperty(orig, name);
copyProperty(dest, name, value);
} catch (NoSuchMethodException e) {
// Should not happen
}
}
}
}
}
然后,您可以使用该方法复制除不同属性以外的所有属性:
import java.lang.reflect.InvocationTargetException;
public class B {
// ...
public static B fromA(A objA) {
B objB = new B();
// Copy common properties
try {
new MyBeanUtilsBean().copyPropertiesExcept(objB, objA, "d");
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
// Explicitly copy specific properties
objB.setD(new IntWrapper(objA.getD()));
return objB;
}
}
您也可以尝试使用complete working example。
答案 2 :(得分:-1)
我将为class B
创建一个构造函数,该构造函数接受所需的类型并将其转换。
class B {
int a;
Double b;
public B(int a, int b) {
this.a = a;
this.b = new Double(b);
}
}