可靠地将任何对象转换为字符串,然后再返回

Posted

技术标签:

【中文标题】可靠地将任何对象转换为字符串,然后再返回【英文标题】:Reliably convert any object to String and then back again 【发布时间】:2012-02-11 19:38:33 【问题描述】:

是否有可靠的方法将任何对象转换为字符串,然后再转换回同一个对象?我见过一些例子,人们使用toString() 转换它们,然后将该值传递给构造函数以再次重建对象,但并非所有对象都有这样的构造函数,因此该方法不适用于所有情况。有什么办法?

【问题讨论】:

【参考方案1】:

是的,它叫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);
 

【讨论】:

你忘了提到base64,以便能够将序列化状态变为String并再次返回=) 您需要访问该类才能执行此操作。如果您从无法访问的地方导入课程怎么办? 如果那个类不是最终的,如果它没有引用另一个不可序列化的对象,如果你没有任何设计问题,你可以将它子类化,然后你可以序列化这个子类。好吧我没试过:) 这可能会导致无效标头异常!将 String 更改为 byte[] 就可以了 如果平台语言环境是 UTF,或者其他一些对字符串编码的无效字节序列挑剔的编码,这将失败。【参考方案2】:

这是代码:

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();         

【讨论】:

添加Base64的依赖【参考方案3】:

Serialize 为字节数组,转换为 Base64。然后将Base64解码回字节数组并反序列化。

【讨论】:

【参考方案4】:

在所有情况下都不起作用。一个对象可能,例如,包含对处理其状态的其他 JVM 的引用,并且您可能无法恢复此状态。

您将遇到的其他问题包括开放流、侦听套接字以及来自外部世界的几乎所有其他问题。

无需重复大多数至少有两位 Java 核心工程师说序列化是 最大的错误之一是 Java 中一个最糟糕的特性,也就是说,定稿后。 (不过我确实喜欢序列化,它很方便。但它不会总是工作。)

【讨论】:

@最后一段 他们有吗?我的意思是我们需要某种方式来持久化对象,虽然它们如何实现序列化肯定存在问题,但它似乎仍然是必不可少的东西。如果他们真的开始列出 Java 中的错误,我认为序列化不会出现在我的前 10 名中;) @Voo 好吧,到目前为止,我只听到 Mark Reinhold 和 Josh Bloch 说序列化是 Java 中最糟糕的部分,并且它在视频中被捕捉到:parleys.com/#st=5&id=2866(希望这是一个开放和免费的演示文稿) 在 35:14 左右。也就是说,最终确定是在一秒钟内完成的,而且承认情况更糟。【参考方案5】:

一种方法是使用 JSON。对于 Java 中的特定实现,答案可能在这篇文章中给出:

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

使用 JSON 足够可靠,可用于 Web 应用程序开发 (Ajax)。

【讨论】:

【参考方案6】:

是的,就是序列化可以使用,ObjectInputStream.readObject和ObjectOutputStream.writeObject。请看下面的例子:

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();

【讨论】:

相信你是想写 os.writeObject(myClass);【参考方案7】:

您可以使用来自org.apache.commons 的 SerializationUtils。 它提供了serializedeserialize方法

【讨论】:

注意是序列化成byte[],不是String

以上是关于可靠地将任何对象转换为字符串,然后再返回的主要内容,如果未能解决你的问题,请参考以下文章

安全地将 JSON 字符串转换为对象

Unity JsonUtility 没有正确地将字符串转换为对象

怎样在java代码里获取一个json对象,然后对其进行排序,排好了之后,再返回给json?

如何最好地将 ClientRect / DomRect 转换为普通对象

有没有更好的方法然后使用 Lynx 在 PHP 中可靠地将 HTML 转换为纯文本

将对象转换为 plist 文件,然后转换为数据