42

Is there a reliable way to convert any object to a String and then back again to the same Object? I've seen some examples of people converting them using toString() and then passing that value into a constructor to reconstruct the object again but not all objects have a constructor like this so that method wont work for all cases. What way will?

user596186
  • 579
  • 1
  • 7
  • 16

7 Answers7

67

Yes, it is called serialization!

 String serializedObject = "";

 // serialize the object
 try {
     ByteArrayOutputStream bo = new ByteArrayOutputStream();
     ObjectOutputStream so = new ObjectOutputStream(bo);
     so.writeObject(myObject);
     so.flush();
     serializedObject = bo.toString();
 } catch (Exception e) {
     System.out.println(e);
 }

 // deserialize the object
 try {
     byte b[] = serializedObject.getBytes(); 
     ByteArrayInputStream bi = new ByteArrayInputStream(b);
     ObjectInputStream si = new ObjectInputStream(bi);
     MyObject obj = (MyObject) si.readObject();
 } catch (Exception e) {
     System.out.println(e);
 }
Andrew
  • 13,757
  • 13
  • 66
  • 84
  • 7
    You forgot to mention base64, so that to be able to get a serialized state to a `String` and back again =) – alf Jan 16 '12 at 22:36
  • You need access to the class to do this. What if you're importing the class from somewhere where you don't have access to? – user596186 Jan 16 '12 at 22:37
  • if that class is not final, if it is not referring another non-serializable objects and if you dont have any design problem you can subclass it and then you can serialize this subclass. Well I didnt try:) – HRgiger Jan 17 '12 at 00:47
  • 7
    This may cause invalid header exception! change String to byte[] and it works – Houcheng Aug 15 '14 at 05:41
  • 3
    If the platform locale is UTF, or some other encoding that is picky about invalid byte sequences for string encoding, this will fail. – KarlP Jan 07 '16 at 20:44
  • What represents **myObject**?Is a String or can it be any object? – sixfeet Nov 15 '16 at 15:32
  • I got the error during deserialization: "invalid stream header: EFBFBDEF", then I found this post: https://stackoverflow.com/questions/46818958/invalid-stream-header-efbfbdef-when-converting-object-from-byte-string. Basically: String is not a container for binary data. You need to pass around the original byte array, or hex- or base64-encode it. After using base64-encode/decode, my deserialization was able to work. – JackOuttaBox Jan 22 '20 at 03:50
21

This is the code:

try {
    ByteArrayOutputStream bo = new ByteArrayOutputStream();
    ObjectOutputStream so = new ObjectOutputStream(bo);
    so.writeObject(stringList);
    so.flush();
    redisString = new String(Base64.encode(bo.toByteArray()));       
} 
catch (Exception e) {
    e.printStackTrace();
}

try {
    byte b[] = Base64.decode(redisString.getBytes()); 
    ByteArrayInputStream bi = new ByteArrayInputStream(b);
    ObjectInputStream si = new ObjectInputStream(bi);
    List<String> stringList2 = (List<String>)si.readObject();
    System.out.println(stringList2.get(1));          
} 
catch (Exception e) {
    e.printStackTrace();         
}
pavjel
  • 486
  • 10
  • 25
Ashwini Adlakha
  • 231
  • 2
  • 2
12

Serialize to byte array, convert to Base64. Then decode Base64 back to byte array and deserialize.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
5

None will work in all cases. An object may, e.g., contain references to other JVMs handling their state, and this state may be not available for you to restore.

Additional problems you're going to meet will include open streams, listening sockets, and almost anything else from the outer world.

There's no need to repeat that most at least two of Java core engineers say that serialization was one of the greatest mistakes a single worst feature in Java, that is, after finalization. (I do love serialization nevertheless, it's handy. But it won't always work.)

alf
  • 8,377
  • 24
  • 45
  • @last paragraph They do? I mean we need some kind of way to persist objects and while there certainly are issues with how they implemented serialization it still seems an essential thing to have. And if they really started listing mistakes in Java, I think serialization wouldn't come up anywhere in the top10 for me ;) – Voo Jan 16 '12 at 23:11
  • @Voo well, so far I only heard Mark Reinhold and Josh Bloch saying that serialization is the single worst part in Java, and it's caught on video: http://www.parleys.com/#st=5&id=2866 (hope it's an open and free presentation) at around 35:14. That said, finalization came in a second, and it was admitted to be even worse. – alf Jan 17 '12 at 10:11
3

One way is to use JSON. For implementation specific in Java, the answer might be given in this post:

java code corresponding to Newtonsoft.Json.JsonConvert.SerializeObject(Object source,Newtonsoft.Json.JsonSerializerSettings()) in .net?

Using JSON is reliable enough that it's used for web application development (Ajax).

Community
  • 1
  • 1
Kevin Le - Khnle
  • 10,579
  • 11
  • 54
  • 80
3

Yes, it is Serialization You can use, ObjectInputStream.readObject and ObjectOutputStream.writeObject. Please see below example:

MyClass myClass = new MyClass();
FileOutputStream fileStream = new FileOutputStream("myObjectFile.txt");
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(os);
os.close();

FileInputStream fileInStream = new FileInputStream("myObjectFile.txt");
ObjectInputStream ois = new ObjectInputStream(fileInStream);
MyClass myClass2 = ois.readObject();
ois.close();
HRgiger
  • 2,750
  • 26
  • 37
0

You can use SerializationUtils from org.apache.commons.
It provides the methods serialize and deserialize

Roberto
  • 4,524
  • 1
  • 38
  • 30