JAVA如何在不复制新实例引用的情况下更改实例字段值[重复]

Posted

技术标签:

【中文标题】JAVA如何在不复制新实例引用的情况下更改实例字段值[重复]【英文标题】:JAVA How to change instance fields values without copying new instance reference [duplicate] 【发布时间】:2015-04-03 17:47:30 【问题描述】:

假设我有 A 类

public class A 
    private int field1;
    private String field2;
    ...

我创建 A 的新实例,然后创建 A 的第二个实例:

A a1 = new A();
A a2 = new A();

是否有任何简单的方法(反射左右)将字段从a2复制到a1而不将实例a2分配给a1(我不想更改实例a1的引用,仅其字段的值)?我知道我可以通过某种方法手动完成,但如果有很多字段,它有点不实用。

我在想是否有办法克服反射?

有人有这方面的经验吗?

【问题讨论】:

您要使用与 a1 相同的引用还是要深拷贝? 你考虑过定义拷贝构造函数,还是实现深拷贝? 【参考方案1】:

你可以使用

org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)

见here

【讨论】:

应该对字段进行某种注释吗?因为在我的情况下,调用 copyProperties 方法后我看不到任何变化。 我读到 BeanUtils 只复制公共字段:( 您可以尝试添加公共 getter/setter 吗? 我有公共的 getter/setter :(【参考方案2】:

您需要考虑很多事情,并且可以根据要求采取多种方法。使用反射你可以像这样

    A a1  //the original a
    A a2 = new A();  //the "duplicate"

    Field[] fields = A.class.getDeclaredFields();
    for (Field f : fields)
        f.setAccessible(true); //need that if the fields are not 
        //accesible i.e private fields
        f.get(a1);
        f.set(a2, f.get(a1));
    

请注意,a2 不是 a1 的深层副本,但它分配了与 a1 相同的引用。这意味着如果你的 A 类有一个像这样的 B 类的对象字段

    class A  
          B b;
    
    class B  
        public String myString;
    

那么在你创建了一个重复的 a2 之后,更改 b 对象的 myString 将同时反映到 a1 和 a2。这是因为 a1 和 a2 都引用了同一个 B 实例。

【讨论】:

谢谢,它的工作原理,我有上面描述的简单案例。

以上是关于JAVA如何在不复制新实例引用的情况下更改实例字段值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在不混淆字段的情况下声明复数? [复制]

如何在不停机的情况下更改 AWS-RDS 实例类型?

如何在不更改原始数组的情况下更改函数中的数组? [复制]

在不更改公共 IP 的情况下增加 EC2 容量

如何在不创建新的表单实例的情况下在表单之间切换?

如何在不重新插入的情况下刷新ListBox中的项目文本?