【问题标题】:Copy one Java object to another将一个 Java 对象复制到另一个
【发布时间】:2014-04-24 20:29:39
【问题描述】:

将一个类的一个 Java 对象复制到同一类的另一个对象的最佳方法是什么?我尝试了 BeanUtil.copyProperties 但由于某种原因它不起作用。该类是一个复杂的类。 (类包含另一个类对象等)

我的目标是通过休眠功能按顺序填充值

Public Response getOrder(Order order, Ticket ticket) {

order = OrderManager.getOrderByTicket(ticket); //Hibernate function This doesn't work, order object gets a new reference

}

试过这样做

Public Response getOrder(Order order, Ticket ticket) {

Order temp = OrderManager.getOrderbByTicket(ticket);

//Now I want to copy temp to order

}

【问题讨论】:

  • 您应该提供更多信息和/或一些示例代码 - 或者如果您遇到异常则提供堆栈跟踪,以便我们更好地帮助您找出问题。

标签: java object copy javabeans pojo


【解决方案1】:

要使用 Serialize / DeSerialize 进行深拷贝,您可以使用如下代码,

public Object deepCopy(Object input) {

    Object output = null;
    try {
        // Writes the object
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(input);

        // Reads the object
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        output = objectInputStream.readObject();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return output;
}

【讨论】:

  • 问题是我通过 5 个函数传递一个对象,并希望使用休眠分配值。当我执行 obj = getObj() 时,它会丢失它的引用传递,并且更改不会反映回主函数。我正在尝试执行 temp = getObj() 并尝试将值从 temp 复制到 obj。我认为您的示例行不通,因为如果我使用 obj = deepCopy (temp),我将回到第一方
  • 不用担心通过引用传递值和所有。这是在 Hibernate 环境中使用的代码,它只是对给定对象和所有子对象进行复制(从数据库中读取,可用于作为新记录集再次插入)。
【解决方案2】:

如果所有字段都是可序列化的,那么您可以使用ObjectOutputStreamObjectInputStream

如果您在序列化和反序列化过程中需要特殊处理,请实现特殊方法writeObject()readObject()

请查看IO: Custom Reading and Writing with Serializable


示例代码:

    class MyClass implements Serializable {
        private static final long serialVersionUID = 1L;
        String str;
        List<Integer> list = new ArrayList<Integer>();

        public MyClass(String str) {
            this.str = str;
        }
    }

    MyClass obj1 = new MyClass("abc");
    obj1.list.add(1);

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(buffer);
    oos.writeObject(obj1);
    oos.close();

    byte[] rawData = buffer.toByteArray();
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(rawData));
    MyClass obj2 = (MyClass) ois.readObject();

    System.out.println(obj2.str);
    System.out.println(obj2.list.get(0));

【讨论】:

    【解决方案3】:

    如果反射真的很重要或很耗时,我想你可以使用反射,但在我看来,有两个主要选择

    • 一个 如果您有权访问该类,只需实现 Clonable 并让 clone 方法生成对象及其所有子对象的深层副本。

    • 两个 手动编码。这可能既费时又无聊,但它适用于所有情况。

    【讨论】:

      【解决方案4】:

      我相信您说的是“深度”副本。

      这里详细介绍了一个类似的问题和各种解决方案:

      How do you make a deep copy of an object in Java?

      最简单的方法似乎是序列化对象然后反序列化它。

      【讨论】:

        【解决方案5】:

        最好这样做:

        Public Response getOrder(Request request) {
        
        Order temp = OrderManager.getOrderbByTicket(request.getTicket());
        request.setOrder(temp);
        
        
        //process the response
        
        }
        

        这将解决将订单返回给函数调用者的问题。如果您希望调用者获得深层副本而不是在将其设置为请求之前对其进行序列化和反序列化

        【讨论】:

        • 问题是我通过 5 个函数传递一个对象,并希望使用休眠分配值。当我执行 obj = getObj() 时,它会丢失它的引用传递,并且更改不会反映回主函数。我正在尝试执行 temp = getObj() 并尝试将值从 temp 复制到 obj。我认为您的示例行不通,因为如果我使用 obj = deepCopy (temp),我将回到第一方
        • 说实话,我不是 100% 理解你的问题。您想保留引用但还想要整个图的副本(您编写的对象很复杂,所以我假设了更多级别)。您可以发布一些示例以便更清楚吗?你的意思是通过 Hibernate 分配值,Hibernate 会填充它们,对吧?之后您是否想继续参与会议?
        • getOrder 有 2 个参数,但你只通过了一个?
        • 啊好的,现在我开始明白了,你要返回响应并修改参数引用。我认为这是不可能的。您应该将其打包到像 Response.setTicket(Ticket ticket) 这样的容器对象中,或者如果不可能,则使用属性票和订单创建一个请求类,然后​​:request.setOrder(OrderManager.getOrder(request.getTicket()) )
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-07
        • 2014-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多