当我为一个问题浪费了很多时间后,我发现在Java中Object类
不可序列化。
那么有没有人知道其他不可序列化的类或者任何一种检查类是否可序列化的方法?
当我为一个问题浪费了很多时间后,我发现在Java中Object类
不可序列化。
那么有没有人知道其他不可序列化的类或者任何一种检查类是否可序列化的方法?
if(someObj instanceof Serializable) // recommended because it uses
// the byte code instruction INSTANCEOF
或者if(Serializable.class.isInstance(someObj))
如果需要在运行时替换Class
,那么使用Class.isInstance(someObj)
是有意义的。
例如:
Class<?> someClass == ....; // assign a class object reference dynamically
if(someClass.isInstance(someObj))
Serializable
,请查看官方文档:https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html。如果你指的是`java.util.Date`,同样适用。其次,这个责任在类的程序员身上。如果你将一个类标记为`Serializable`,你必须确保所有非短暂实例字段也是可序列化的。或者你可以编写自己的序列化方法(writeObject、readObject)。请参阅http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html。 - René Linkjava.util.List
类型字段的类。java.util.List
不扩展 Serializable
。现在,它取决于设置的具体列表类型是否可序列化。将字段设置为 ArrayList
将起作用。其他列表实现可能无法正常工作。比如由持久性框架设置的延迟加载列表。 - René Link仅使用instanceof
是不完全可靠的,就像以下代码所示。最好的方法是检查您尝试进行编组的类的源代码,如果您有它们,或者如果没有,您可以希望供应商正确处理了这件事。
class A {
final int field;
/*
// uncomment this ctor to make class "more" serializable
A() {
this.field = -1;
}
*/
A(int field) {
this.field = field;
}
}
class B extends A implements Serializable {
B(int field) {
super(field);
}
public String toString() {
return "B{field=" + field + "}";
}
}
class Test {
public static void main(String[] args) {
System.out.println(Serializable.class.isAssignableFrom(B.class));
B b = new B(11);
try {
ByteArrayOutputStream bf = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bf);
oos.writeObject(b);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bf.toByteArray()));
Object o = ois.readObject();
System.out.println(o.toString());
} catch (Exception e) {
System.out.println("Not exactly Serializable");
e.printStackTrace();
}
}
}
implements Serializable
并不足以实际序列化对象。你完全正确,但我认为这不是被问到的问题(或者原帖作者需要更具体地表达)。 - m0skit0@Test
public void testIfYourClassIsSerilaizable() {
boolean exceptionThrown = false;
try {
YourClass obj = new YourClass();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
byte [] data = bos.toByteArray();
} catch(IOException ex) {
exceptionThrown = true;
}
Assert.assertFalse(exceptionThrown);
}
因此,基于这一点,如果YourClass或其属性没有实现Serializable接口,上述测试将抛出异常,使该类不可序列化。
if (yourObjectInstance instanceof Serializable) {
// It is
} else {
// It is not
}
yourObjectInstance
为null
,那么会进入else
部分,因为无论引用是关于什么类的,null
都不是Serializable
。此外,正如Victor Sorokin指出的那样,一个类实现Serializable
并不意味着它实际上可以被序列化。有些人建议使用instanceof运算符,但它做的是另一件事情:如果引用为空,则返回false,即使该类实现了Serializable接口!
而且这也适用于Class.isInstance(Object obj)
Serializable.class.isInstance(null)
也将返回 false。变量声明的类型是什么并不重要,如果引用为 null,那么 instanceof
和 Class.isInstance()
都会返回 false。 - René Linknull
不是一个对象实例,因此它没有实现Serializable
接口,所以这个行为是完全正确的。 - m0skit0你可以检查
someObject instanceof Serializable
如果someObject
实现了Serializable
接口,这将评估为true
您可以检查类是否可序列化:
if(someObj instanceof Serializable)