Reputation: 9935
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
Upvotes: 3
Views: 1325
Reputation: 7717
No CyCDemo, there are a lot of issues about the Cloneable interface and the reason of and the reasons why Java has not implemented a deep copy.
In any case get an eye there:
https://code.google.com/p/cloning/
Upvotes: 0
Reputation: 8825
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.
Upvotes: 3