【转载】java 复制对象有哪些方式

原文地址:https://my.oschina.net/huangweiindex/blog/1858700

java 复制对象有哪些方式

 

Apache的 Common beanutils库

org.apache.commons.beanutils.BeanUtils.copyProperties(dest,origin);

Springframework 的BeanUtil

依赖:

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
BeanUtils.copyProperties(source, target);

Object 流

使用 ObjectInputStream

 /**
     * This method makes a "deep clone" of any Java object it is given.
     */
    public static Object deepClone(Object object) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            ByteArrayInputStream bais = new ByteArrayInputStream(
                    baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

or

 /**
     * Returns a copy of the object, or null if the object cannot be serialized.<br>
     * refre:http://javatechniques.com/blog/faster-deep-copies-of-java-objects/
     */
    public static Object copy(Object orig) {
        Object obj = null;
        try {
            // Write the object out to a byte array
            FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(fbos);
            out.writeObject(orig);
            out.flush();
            out.close();

            // Retrieve an input stream from the byte array and read
            // a copy of the object back in.
            ObjectInputStream in = new ObjectInputStream(fbos.getInputStream());
            obj = in.readObject();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        }
        return obj;
    }

json序列化

先序列化对象 为json;
然后对该json字符串 反序列化为新的对象.

/***
     * 2018/7/18
     */
    @Test
    public final void test_CopyObject() {
        Student student = new Student();
        student.setName("liuyu");
        System.out.println("复制前 :" +student.hashCode());
        String json = HWJacksonUtils.getJsonP(student);

        Student student2 = (Student)HWJacksonUtils.deSerialize(json, Student.class);
        System.out.println("student2 :" + student2.getName());
        System.out.println("复制后 :" +student2.hashCode());
    }

使用开源库 DozerBeanMapperBuilder

依赖:

  <dependency>
            <groupId>com.github.dozermapper</groupId>
            <artifactId>dozer-core</artifactId>
            <version>6.2.0</version>
        </dependency>

测试代码:

 @Test
    public final void test_Dozer() {
        Student student = new Student();
        student.setName("liuyu2");

        Mapper instance = DozerBeanMapperBuilder.buildDefault();
        Student student2 = instance.map(student, Student.class);
        System.out.println("student2 :" + student2.getName());
    }

FastByteArrayOutputStream 源码

package com.io.hw.file.util;

import java.io.InputStream;
import java.io.OutputStream;

/***
 * refre:http://javatechniques.com/blog/faster-deep-copies-of-java-objects/<br>
 * ByteArrayOutputStream implementation that doesn't synchronize methods
 * and doesn't copy the data on toByteArray().
 *
 * @author huangwei
 * @since 2015年3月5日
 */
public class FastByteArrayOutputStream extends OutputStream {
    /**
     * Buffer and size
     */
    protected byte[] buf = null;
    protected int size = 0;

    /**
     * Constructs a stream with buffer capacity size 5K
     */
    public FastByteArrayOutputStream() {
        this(5 * 1024);
    }

    /**
     * Constructs a stream with the given initial size
     */
    public FastByteArrayOutputStream(int initSize) {
        this.size = 0;
        this.buf = new byte[initSize];
    }

    /**
     * Ensures that we have a large enough buffer for the given size.
     */
    private void verifyBufferSize(int sz) {
        if (sz > buf.length) {
            byte[] old = buf;
            buf = new byte[Math.max(sz, 2 * buf.length)];
            System.arraycopy(old, 0, buf, 0, old.length);
            old = null;
        }
    }

    public int getSize() {
        return size;
    }

    /**
     * Returns the byte array containing the written data. Note that this
     * array will almost always be larger than the amount of data actually
     * written.
     */
    public byte[] getByteArray() {
        return buf;
    }

    public final void write(byte b[]) {
        verifyBufferSize(size + b.length);
        System.arraycopy(b, 0, buf, size, b.length);
        size += b.length;
    }

    public final void write(byte b[], int off, int len) {
        verifyBufferSize(size + len);
        System.arraycopy(b, off, buf, size, len);
        size += len;
    }

    public final void write(int b) {
        verifyBufferSize(size + 1);
        buf[size] = (byte) b;
        size++;
    }

    public void reset() {
        size = 0;
    }

    /**
     * Returns a ByteArrayInputStream for reading back the written data
     */
    public InputStream getInputStream() {
        return new FastByteArrayInputStream(buf, size);
    }
}

参考:
https://github.com/DozerMapper/dozer

原文地址:https://www.cnblogs.com/chaos-li/p/10895105.html