java 将一个类的字段复制到另一个类的相同字段

omtl5h9j  于 2023-05-12  发布在  Java
关注(0)|答案(4)|浏览(174)

我有个问题但我不知道确切的术语,所以很难解释。希望有人能理解。我会尽我所能描述的。我觉得这和parsing有很大关系
假设有两个班级。在这两个类中,我都有一些变量,比如字符串(为了简单起见,变量类型可以是任何),它们有相似的名字

Eg:
    class ClassA{
        String x,y,z;
    }

    class ClassB{
        String x,y,z;
    }

现在,我需要的是,我需要复制一个类的变量值到其他类对应的变量值。

Eg:
    ClassA aa=new ClassA();
    ClassB bb=new ClassB();
    //set bb's variables
    aa.x=bb.x;
    aa.y=bb.y;
    aa.z=bb.z;

就像那样
但请注意,我需要的不是上面的方法。我希望有一种方法可以写一个简单的方法,这样它就可以通过传递给它的名字来识别相关的变量。然后它将相应地进行赋值。
我想象的方法是这样的,

void assign(String val){        
    // aa.<val>=val
}

例如,如果你将bb.x传递给assign(...)方法,那么它将执行aa.x=bb.x赋值。
希望这足够清楚。一定有更好的解释。如果有人知道,请编辑后(+标题),使其更清楚(但保存我的想法)..
请让我知道是否有办法实现这一点。
谢谢!

qltillow

qltillow1#

Dozer很好,看看Jean-Remy的回答。
此外,如果变量具有符合JavaBeans标准的getter和setter,则有许多技术可以帮助您,例如。Apache Commons / BeanUtils

示例代码(未测试):

final Map<String, Object> aProps = BeanUtils.describe(a);
final Map<String, Object> bProps = BeanUtils.describe(b);
aProps.keySet().retainAll(bProps.keySet());
for (Entry<String, Object> entry : aProps.entrySet()) {
    BeanUtils.setProperty(b,entry.getKey(), entry.getValue());
}

更新:

如果你没有getter和setter,这里有一个快速的技巧,只要字段具有共同的名称和类型,就可以将字段值从一个类复制到另一个类。我还没有测试过,但作为一个起点应该是可以的:

public final class Copier {

    public static void copy(final Object from, final Object to) {
        Map<String, Field> fromFields = analyze(from);
        Map<String, Field> toFields = analyze(to);
        fromFields.keySet().retainAll(toFields.keySet());
        for (Entry<String, Field> fromFieldEntry : fromFields.entrySet()) {
            final String name = fromFieldEntry.getKey();
            final Field sourceField = fromFieldEntry.getValue();
            final Field targetField = toFields.get(name);
            if (targetField.getType().isAssignableFrom(sourceField.getType())) {
                sourceField.setAccessible(true);
                if (Modifier.isFinal(targetField.getModifiers())) continue;
                targetField.setAccessible(true);
                try {
                    targetField.set(to, sourceField.get(from));
                } catch (IllegalAccessException e) {
                    throw new IllegalStateException("Can't access field!");
                }
            }
        }
    }

    private static Map<String, Field> analyze(Object object) {
        if (object == null) throw new NullPointerException();

        Map<String, Field> map = new TreeMap<String, Field>();

        Class<?> current = object.getClass();
        while (current != Object.class) {
            for (Field field : current.getDeclaredFields()) {
                if (!Modifier.isStatic(field.getModifiers())) {
                    if (!map.containsKey(field.getName())) {
                        map.put(field.getName(), field);
                    }
                }
            }
            current = current.getSuperclass();
        }
        return map;
    }
}

调用语法:

Copier.copy(sourceObject, targetObject);
pgccezyw

pgccezyw2#

你听说过道瑟吗:http://dozer.sourceforge.net/
推土机
Dozer是一个JavaBean到JavaBean的Map器,它递归地将数据从一个对象复制到另一个对象。通常,这些Java Bean将具有不同的复杂类型。
Dozer支持简单属性Map、复杂类型Map、双向Map、隐式-显式Map以及递归Map。这包括Map也需要在元素级别Map的集合属性。
Dozer允许您MapJava Bean:

  • 使用它们的名称(隐式Map),即将ClassA.xMap到ClassB.x
  • 提供了使用(非常简单的)XML或注解配置Map具有不同名称的不同结构(显式Map)的能力。

以下是图书馆网站上的一个XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">
          
  <mapping> 
    <class-a>org.dozer.vo.TestObject</class-a>
    <class-b>org.dozer.vo.TestObjectPrime</class-b>   
    <field>
      <a>one</a>
      <b>onePrime</b>
    </field>
  </mapping>  

      <!-- SNIP ... -->

</mappings>

这将把对象org.dozer.vo.TestObjectMap到TestObjectPrime,把所有相同的变量Map到一起(就像在您的例子中一样),把变量TestObjectFoo.oneFooMap到TestObjectFooPrime. oneFooPrime。
很棒,不是吗?

oxosxuxt

oxosxuxt3#

你看。使用BeanUtils.copyProperties(newObject, oldObject);即可

1l5u6lss

1l5u6lss4#

新的答案
我建议去多佛看看,因为它看起来很简单。
第二种选择是将类序列化为XML,并仅对匹配的成员反序列化为目标类。
我在评论中提到的第三个选项是使用反射-http://java.sun.com/developer/technicalArticles/ALT/Reflection/
这种技术允许一个很好的设计模式,称为Introspection -Java introspection and reflection,它反过来允许你发现某个类的成员。
现在,已经说过了,我们可以简单地“发现”ClassA的成员,用他们的名字填充一个ArrayList,发现ClassB的成员,用他们的名字填充另一个ArrayList,并复制交集的值。至少这是我的想法。

相关问题