有没有办法检查java中的对象是否可序列化?
我发现java中的有没有办法检查java中的对象是否可序列化?,java,Java,我发现java中的对象类最终在java中是不可序列化的,因为我已经为一个问题浪费了很多时间。 那么,谁能知道另一个类的那些不可序列化的,或者用什么方法来检查该类是否可序列化?您可以检查 someObject instanceof Serializable 如果someObject实现了Serializable接口,则这将计算为true if(someObj instanceof Serializable) // recommended because it uses
对象类
最终在java中是不可序列化的,因为我已经为一个问题浪费了很多时间。那么,谁能知道另一个类的那些不可序列化的,或者用什么方法来检查该类是否可序列化?您可以检查
someObject instanceof Serializable
如果someObject
实现了Serializable
接口,则这将计算为true
if(someObj instanceof Serializable) // recommended because it uses
// the byte code instruction INSTANCEOF
或
如果类
在运行时应该是可替换的,那么使用Class.isInstance(someObj)
是有意义的
例如:
Class<?> someClass == ....; // assign a class object reference dynamically
if(someClass.isInstance(someObj))
Class-someClass==…;//动态分配类对象引用
if(someClass.isInstance(someObj))
是
请注意,如果yourObjectInstance
为null
,则无论引用是关于哪个类,都将以null
不可序列化的形式输入部分
另外,让类实现可序列化并不意味着它实际上可以序列化。一些人建议使用instanceof操作符,但它做了另一件事:如果引用为null,则返回false,即使该类实现可序列化!
这也适用于Class.isInstance(objectobj)
仅使用实例的
不100%可靠,如下代码所示。最好的办法是检查您试图封送的类的源(如果有),或者,如果没有,您可能希望
班主任做对了
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();
}
}
}
您可以检查类是否可序列化:
if(someObj instanceof Serializable)
如果对象是可序列化的,则应该能够将其转换为字节数组。
因此,您可以使用此测试方法,并确保在序列化它时不会引发异常
@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);
}
因此,基于此,如果您的类或其属性未实现可序列化,则上述测试将引发异常,使该类不可序列化。这可能有助于您我尝试在此处编写一个尽最大努力的单元测试,以检查接口或类是否完全可远程/序列化:但是可序列化.class.isInstance(null)
也将返回false。变量声明的类型并不重要。如果引用为null,则instanceof
和Class.isInstance()
将返回false。null
不是对象实例,因此它没有实现可序列化
,因此行为完全正确。我没有说它不正确。我只是澄清了它的行为。当您有一个isSerializable(Object obj){}方法时,您不能保证调用者将null放入其中。您正在演示实现可序列化的
不足以实际序列化对象。你是完全正确的,但我认为这不是要问的问题(或者OP必须更具体)。你一针见血,而检查某个东西是否可序列化比检查它是否实现了可序列化
。某些可序列化的类不可序列化
(枚举、日期
等)。有些是,有些不是(例如,那些有不可序列化的成员)。@wu lee好吧,第一个枚举是可序列化的,并实现serializable
请参阅javadoc:。这同样适用于Date
(如果您的意思是java.util.Date
)。第二点是类程序员的责任。如果您将一个类标记为可序列化
,则必须注意所有非瞬态实例字段也可序列化。或者您必须编写自己的序列化方法(writeObject、readObject)。看一看关于日期等的观点。然而,我认为第二点是正确的,这就是为什么检查对象是否可序列化比您的答案(当前接受的答案)所建议的要困难得多。它还需要做的不仅仅是测试序列化是否有效——例如,我发现类型不可序列化的
字段如果为null
,实际上会序列化,如果您没有注意到这一点,可能会导致错误的安全感和运行时意外的异常。@wu lee我理解您的观点。在我看来,开发人员也必须关注javadoc,如果我阅读了Serializable的javadoc,我很清楚该怎么做。但你也是对的,事情可能会更复杂。例如,假设一个类的字段类型为java.util.List
。java.util.List
不扩展Serializable
。现在,它取决于设置的具体列表类型是否可序列化。将字段设置为ArrayList
将起作用。其他列表实现可能不起作用。就像持久性框架设置的延迟加载列表一样,我认为这是测试类是否可序列化的唯一方法,instanceOf并不是一种完全证明这一点的方法。
if(someObj instanceof Serializable)
@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);
}