就像标题所说的那样,有没有办法检查一个对象是否可序列化,如果没有,可以在运行时这样做吗?
答案 0 :(得分:11)
简短回答 - 不。
更长的答案 - 是的,使用字节码操作,例如使用asm。但你应该考虑是否需要这样做。序列化是一个严重的问题(Effective Java有一整章关于序列化)
顺便说一句,有二进制序列化的替代方法,不需要实现Serializble
的对象(正如Jacob在评论中指出的那样):
java.beans.XMLEncoder.encode(..)
是ObjectOutputStream
答案 1 :(得分:1)
正如其他人所说......简答是否。
您可以使用http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html中所述的代理对象在运行时向任何旧对象添加接口。这也包括java.io.Serializable。但是,为了使代理对象有用,它必须维护对原始对象的内部引用,在您的情况下,它不实现Serializable。您的代理对象可以序列化的唯一方法是将原始对象的内部引用设置为瞬态字段,这对您来说根本不会太好。
此外,在检查了你的评论后,看起来java序列化肯定不是你想要的,你真的只想序列化为某种字符串格式。其他人提出了各种解决方案,但IMO如果你想要最少量的话,请使用XStream:http://x-stream.github.io/tutorial.html。
答案 2 :(得分:1)
如果有人真的真的需要在运行时使用字节码进行操作。使用库Javassist可以完成此操作:
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("mypackage.MyClass");
cc.addInterface(pool.get("java.io.Serializable"))
答案 3 :(得分:0)
哇。为什么需要在运行时检查它?在编译时确保它更容易吗?使用像这样的代码。
public void someMethod(Serializable serializable){
}
或者你可以使它更复杂。
public interface SerializableInterface implements Serializable{
// bla-bla
}
public void someMethod(SerializableInterface serializable){
}
答案 4 :(得分:0)
除了现有的好答案之外,另一个问题是您是否特别需要Java Serializable用于特定框架,或者只需要能够序列化对象。 对于后者,有比JDK默认选择更多的选择;对于许多用例,替代品比JDK好得多。
如果您不特别需要JDK,那么使用基于JSON或XML的序列化通常是一个不错的选择。
答案 5 :(得分:0)
在运行时检查?当然。 “if(someObject instanceof Serializable)......”。
您想在运行时更改对象的定义吗?很少有理由想要这样做。也许有一种方法可以用反射来做到这一点,但我从来没有理由想做这样的事情。你想要完成什么?
答案 6 :(得分:0)
您可以创建一个带有对象字段的 Serizlize 包装类,然后将您的对象分配给该字段。当您序列化包装类时,它将存储对象,您可以从字段中反序列化和转换您的对象。
public class SerialWrap implements Serializable{
public Object obj;
}
HashMap<String, String> hm = new HashMap<>();
hm.put("great preacher", "Apostle Winston George Baker King Jesus Pentecostal Fellowship Negril, Jamaica");
hm.put("Miracles","Sick healed, cancer healed,God is moving");
SerialWrap wrap = new SerialWrap();
wrap.obj = hm;
ObjectOutputStream.write(wrap)
SerialWrap wrap2 =(SerialWrap)ObjectInputStream.readObject();
hm =(HashMap<String, String>) wrap2.obj;