有没有办法检查java中的对象是否可序列化?

有没有办法检查java中的对象是否可序列化?,java,Java,我发现java中的对象类最终在java中是不可序列化的,因为我已经为一个问题浪费了很多时间。 那么,谁能知道另一个类的那些不可序列化的,或者用什么方法来检查该类是否可序列化?您可以检查 someObject instanceof Serializable 如果someObject实现了Serializable接口,则这将计算为true if(someObj instanceof Serializable) // recommended because it uses

我发现java中的
对象类
最终在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);
}