Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create new instance with the same value?

Tags:

java

Actually, I searched the solution for that in web. I also found Copy an object in Java. In my object, there are a lot mapping. Even I use Cloneable and Copy Constructor, I still need to copy for each fields?

My requirement is to know which data changed between Old Object and New Object.

My object Example Tree :

MotorProposal
    - startDate : Date              ---> can change
    - endDate : Date                ---> can change
    - customer : Cutomer
    - vehicleList : List<Vehicle>   ---> can chnage
        - carNo : String            ---> can change
        - loading : int             ---> can change
        - cubicCapacity : int       ---> can chnage
        - driver : Driver           ---> can change
            - fullName : String     ---> can change
            - address : Stirng      ---> can change
            - license : Stirng      ---> can change
            - expYear : int         ---> can change
        - model : Model

        -there other fields

    -there other fields

Is there another way to create new Instance with the same value without copying for each field?

My expected program

MotorProposal oldProposal = --> come from DB
MotorProposal newProposal = org.someapi.ObjectUtil.newInstance(oldProposal);

Update

Currently, I solve this case Martin Dinov suggested. As below.

ObjCopy.java

public class ObjCopy {
    public static Serializable newInstance(Serializable obj) {
        Serializable result = null;
        try {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(buffer);
            oos.writeObject(obj);
            oos.flush();
            oos.close();

            ByteArrayInputStream in = new ByteArrayInputStream(buffer.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(in);
            return (Serializable)ois.readObject();
        } catch (Exception e) {
            //do nothing
            e.printStackTrace();
        }
        return result;
    } 
}

Test.java

public class Test {
    public static void main(String[] args) {
        Country country = new Country();
        country.setName("Myanmar");
        Province province_1 = new Province();
        province_1.setCountry(country);
        province_1.setName("Yangon");

        Province province_2 = (Province)ObjCopy.newInstance(province_1);
        province_2.getCountry().setName("USA");
        System.out.println(province_1.getName() + "-" + province_1.getCountry().getName());
        System.out.println(province_2.getName() + "-" + province_2.getCountry().getName());
    }
}   

Output

Yangon-Myanmar
Yangon-USA
like image 948
Zaw Than oo Avatar asked Apr 16 '26 22:04

Zaw Than oo


1 Answers

How about Yoni Roit's second proposal from the Stackoverflow link you provide? In other words, serialize and then deserialize the object - so this will result in deep copying your object byte-wise. You need to have your class implement Serializable. As long as all class fields can be serialized, this approach should work. However, serializing and deserializing objects can be quite slow apparently - probably not an issue if you want to do this out of convenience, rather than out of efficiency. Here's a simple example of re-creating a new ArrayList:

    ArrayList<Integer> foo = new ArrayList<Integer>();
    foo.add(5);
    foo.add(3);
    foo.add(1);
    ArrayList<Integer> obj = null;
    // Write the object out to a byte array
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(foo);
    out.flush();
    out.close();

    // Make an input stream from the byte array and read
    // a copy of the object back in.
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
            bos.toByteArray()));
    obj = (ArrayList<Integer>)in.readObject();

In your case, you'd want to type-cast to your specific class of course. This way you don't have to explicitly copy each field in the class.

like image 181
Martin Dinov Avatar answered Apr 19 '26 12:04

Martin Dinov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!