1

Can you help me with understanding on how to implement serialization. I have read lots of about serialization and the code, but I don't know how to implement it if more classes are involved. In my application from the GUI the user's input the regNo, carType and Date information are sent to a coordinating object corObj, that creates car instance with those 3 values.

  1. Where does the serialization code for the car go? Into Car class or into corObj object?
  2. After 3 cars have been serialized how can the 3 cars can be deserialized? Here I'm not asking for the code. For example if the user from GUI will ask corObj object for previously saved cars, where deserialization code should be? In corObj or Car objects?

corObj object keeps the collection of references to each created car instance. So after deserialization how can corObj refer again to those reconstructed car instances?

Would the previously created collection of car instances automatically refer back to reconstructed cars? If not how other objects can get hold of the reference of the reconstructed instances? Could you give me some simple example?

  • 1
    Sounds like (from reading) `Coor` should be the one to serialize/deserialize the actual `Car` objects (since it manages them), but as far as actually being serializable, you just need to ensure all fields are serializable/transient (and it implements Serializable). – Rogue Jun 13 '17 at 13:24
  • a good practice to serialize is to have all objects / subobject that implements Serializable, in order to unsure consistance of your code. This is quick to do, and makes test/ prod like a charm. Also, before serializing it's good to know if it can(t be stored as json instead (much easier format to debug, work on). – jeorfevre Jun 13 '17 at 13:47
  • @jeorfevre You may wanna check out [What is the penalty for unnecessarily implementing Serializable?](https://stackoverflow.com/questions/39079928/what-is-the-penalty-for-unnecessarily-implementing-serializable/39088501#39088501) - should avoid implementing `Serialization` where it's not needed – Vince Jun 13 '17 at 13:51
  • How to get reference to deserialized object? After each object is serialized does it need to be put into some collection? How otherwise would Coor object know how many objects needs to be deserialized? – user8109860 Jun 13 '17 at 13:53

1 Answers1

1

Where does the serialization code for the car go? Into Car class or into corObj object?

Assuming you're using an ObjectOutputStream, the serialized data is streamed to whatever the ObjectOutoutStream is wrapping. It could be to your local storage using a FileInputStream to stream the data to a file on your drive:

File file = new File("car.obj");
FileOutputStream fileOut = new FileOutputStream(file);
ObjectOutputStream objOut = new ObjectOutputStream(fileOut);

objOut.writeObject(new Car()); //write
objOut.close();

FileInputStream fileIn = new FileInputStream(file);
ObjectInputStream objIn = new ObjectInputStream(fileIn);

Car car = (Car) objIn.readObject();

Where the serialized data goes depends on what you pass to the constructor of ObjectOutputStream.

Above shows writing/reading to/from local storage. You can use a ByteArrayOutputStream to keep the data in memory, or a stream from a Socket to send it over a network.

After 3 cars have been serialized how can the 3 cars can be deserialized?

You must keep track of this yourself. Once the serialized data leaves the stream, it's virtually no longer in your application (unless you stream it to memory).

The point of streams is for I/O (input/output) - you are sending the data somewhere via a connection.

It could be kept inside your application by writing to a ByteArrayOutputStream:

ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(arrayOut);

//write object

byte[] data = arrayOut.toByteArray(); //must keep a reference to this data! Contains serialized object

ByteArrayInputStream arrayIn = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(arrayIn);

//read object

Or you can stream it out of your program via FileOutputStream or an output stream from Socket.

File file = new File("car.obj"); //must keep a reference to this file! Specified where serialized object is
ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(file));

//write object

ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));

//read object

corObj object keeps the collection of references to each created car instance. So after deserialization how can corObj refer again to those reconstructed car instances?

You must keep track of where you are streaming those objects to. If streaming to local storage, you must keep track of the file names. If streaming to a ByteArrayOutputStream, you must keep a reference of that byte stream.

Would the previously created collection of car instances automatically refer back to reconstructed cars

No. By deserializing, you are creating a new object. If you serialize an object in a collection, then deserialize the object without ever removing the one from the collection, you now have 2 objects.


I highly recommend reading my answer on What is the penalty for unnecessarily implementing Serializable?. If you serialize an object, the modify the class of that object before deserializing the object, attempting to deserialize that object may fail as the binary data will no longer match.

Vince
  • 14,470
  • 7
  • 39
  • 84
  • Great explanation. What happens if object that had been serialized is updated? Will the change of the object be reflected in a file where it was serialized/saved? If not should object be serialized perhaps just when the program is going to be stopped and object's state needs to be saved or after each object's update that object should serialized again so only up to date object is always saved at any one time? – user8109860 Jun 13 '17 at 19:34
  • @user8109860 If you deserialize an object from local storage and change it's state in memory (update it), it'll no longer match the object in local storage. Same goes for editing the object's class. But that doesn't matter, as deserialization always results in a new object. If you're storing the object for later use, the idea is to deserialize the saved object, then overwrite the serialized object once you want to store again. Although you may want to use a different form of storage. Why are you using object streams? – Vince Jun 13 '17 at 20:01
  • After object is recreated by deserialization and then change its state should to reflect that objects' change, the serialization of that changed object should be invoked again, right? I know its not the best way to save the state of an object, its only quick prototype what I need now, and stream is only way that I familiar with. I tried to set up database in NetBeans but I dont have enough time now to learn and make it working. What would be other quick, easy alternative to save the state of few object in a simple program? – user8109860 Jun 13 '17 at 20:31
  • @user8109860 Yes, but you shouldn't re-serialize every time the state changes, that would be expensive. You should save on certain occasions. Maybe when the program ends, periodically, etc.. If you're only testing, then this is quick state saving. But in production code, you should isolate the state you want to save and write it to either a relational database or a file (encrpyted text, json, properties, etc..). Object streams are useful when storing data in an object oriented DB. If using object streams, you should always isolate state being serialized to it's own class to reduce conflicts – Vince Jun 13 '17 at 21:38