你能让一个对象在运行时可序列化吗?

发布于 2024-09-18 06:23:45 字数 49 浏览 7 评论 0原文

就像标题所说,有没有办法检查一个对象是否可序列化,如果不是,则在运行时使其可序列化?

Just like the title says, is there a way to check if an object is serializable, and if not, make it so at run time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夏の忆 2024-09-25 06:23:45

简短的回答 - 不。

更长的答案 - 是的,使用字节码操作,例如使用 asm。但你应该真正考虑是否需要这样做。序列化是一件严肃的事情(Effective Java 有整整一章关于序列化)

顺便说一句,还有二进制序列化的替代方案,不需要实现 Serializble 的对象(正如 Jacob 在评论中指出的那样):

  • XML - java.beans.XMLEncoder.encode(..)ObjectOutputStream JSON 的 xml 版本
  • - 像 Jacskon、Gson 这样的框架让您可以用一行序列化一个对象。

Short answer - no.

Longer answer - yes, using byte-code manipulation, for example with asm. But you should really consider whether this is needed. Serialization is a serious matter (Effective Java has a whole chapter on serialization)

Btw, there are alternatives to binary serialization, that do not require the object implementing Serializble (as pointed by Jacob in the comments):

  • XML - java.beans.XMLEncoder.encode(..) is the xml version of ObjectOutputStream
  • JSON - frameworks like Jacskon, Gson let you serialize an object with one line.
夏尔 2024-09-25 06:23:45

如果有人真的真的需要在运行时使用字节码进行操作。使用库 Javassist 可以做到这一点:

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("mypackage.MyClass");
cc.addInterface(pool.get("java.io.Serializable"))

If somebody really really really need manipulate with bytecode in runtime. With library Javassist can be done this:

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("mypackage.MyClass");
cc.addInterface(pool.get("java.io.Serializable"))
爱你不解释 2024-09-25 06:23:45

正如其他人所说...简短的答案是否定的。

您绝对可以使用代理对象在运行时向任何旧对象添加接口,如 http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html 。这也包括 java.io.Serialized。但是,为了使代理对象有用,它必须维护对原始对象的内部引用,在您的情况下,原始对象没有实现 Serialized。序列化代理对象的唯一方法是将原始对象的内部引用设置为瞬态字段,但这对您没有多大好处。

此外,在检查了您的评论之后,看起来 java 序列化绝对不是您想要的,您实际上只想序列化为某种字符串格式。其他人提出了各种解决方案,但在我看来,如果您想要最少的麻烦,请使用 XStream: http ://x-stream.github.io/tutorial.html

As others have said... Short Answer is No.

You can absolutely add an interface to any old object at runtime by using Proxy objects as described at http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html . This includes java.io.Serializable too. However, in order for a proxy object to be useful, it must maintain an internal reference to the original object, which in your case does not implement Serializable. The only way your proxy object could be serialized is by making the internal reference to the original object a transient field and that wouldn't do you much good at all.

Further, after examining your comments, it looks like java serialization is definitely not what you want and you really just want to serialize to some string format. Others have suggested various solutions, but IMO if you want the least amount of fuss, go with XStream: http://x-stream.github.io/tutorial.html .

讽刺将军 2024-09-25 06:23:45

哇哦。为什么需要在运行时检查它?在编译时确保它不是更容易吗?使用这样的代码。

public void someMethod(Serializable serializable){
}

或者你可以让它变得更复杂。

public interface SerializableInterface implements Serializable{
// bla-bla
}

public void someMethod(SerializableInterface serializable){
}

Whoa. Why would you need it to be checked at runtime? Isn't it easier to ensure it at compile time? Using a code just like this.

public void someMethod(Serializable serializable){
}

Or you can make it more complex.

public interface SerializableInterface implements Serializable{
// bla-bla
}

public void someMethod(SerializableInterface serializable){
}
尹雨沫 2024-09-25 06:23:45

除了现有的好的答案之外,另一个问题是您是否特别需要针对特定​​框架的 Java Serialized,或者只需要能够序列化对象。
对于后者,比 JDK 默认的选择要多得多;对于许多用例来说,替代方案比 JDK 好得多。

如果您不是特别需要 JDK,那么使用基于 JSON 或 XML 的序列化通常是一个不错的选择。

Aside from existing good answers, another question is whether you specifically need Java Serializable for specific framework, or just need to be able to serializer objects.
For latter there are many many more choices than JDK default one; and for many use cases alternatives are much better than JDK one.

If you don't specifically need JDK one, using JSON or XML based serialization is often a good choice.

-柠檬树下少年和吉他 2024-09-25 06:23:45

在运行时检查?当然。 “如果(可序列化的某个对象实例)...”。

您想在运行时更改对象的定义吗?很少有充分的理由想要这样做。也许有一种方法可以通过反思来做到这一点,但我从来没有理由想做这样的事情。你想实现什么目标?

Checking at run time? Sure. "if (someObject instanceof Serializable) ...".

You want to change the definition of an object at run time? There is very rarely a good reason to want to do this. Maybe there's a way to do this with reflection, but I've never had a reason to want to do such a thing. What are you trying to accomplish?

深府石板幽径 2024-09-25 06:23:45

您可以创建一个带有对象字段的 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;

You could create a Serizlize wrapper class with an object field, then assign your object to the field. When you serialize the wrapper class, it will store the object, and you can deserialize and cast your object from the field.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文