可靠地将任何对象转换为字符串,然后再返回
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。
它提供了serialize
和deserialize
方法
【讨论】:
注意是序列化成byte[],不是String以上是关于可靠地将任何对象转换为字符串,然后再返回的主要内容,如果未能解决你的问题,请参考以下文章
Unity JsonUtility 没有正确地将字符串转换为对象
怎样在java代码里获取一个json对象,然后对其进行排序,排好了之后,再返回给json?
如何最好地将 ClientRect / DomRect 转换为普通对象