简体   繁体   English

如果在Serializable接口中使用Java,Java是否会自动使类可序列化?

[英]Does Java make classes Serializable automatically if used in a Serializable interface?

Let's say I have a Serializable interface as follows 假设我有一个Serializable接口,如下所示

public interface SomeInterface extends Serializable {

     public SomeClass getSomething(String someParameter);

}

Will SomeClass be Serializable automatically? SomeClass可以自动序列化? To our surprise, our RMI application runs fine even when SomeClass does not implement Serializable. 令我们惊讶的是,即使SomeClass没有实现Serializable,我们的RMI应用程序也可以正常运行。

Why is this? 为什么是这样?

Will SomeClass be Serializable automatically? SomeClass可以自动Serializable To our surprise, our RMI application runs fine even when SomeClass does not implement Serializable . 令我们惊讶的是,即使SomeClass没有实现Serializable ,我们的RMI应用程序也可以正常运行。

No. 没有。

Serialization is about serializing the (non-transient) state of an object. 序列化是关于序列化对象的(非瞬态)状态。 The presence of a getSomething in the signature of some method doesn't require the state of your instance of a SomeInterface to include a SomeClass instance. 某些方法的签名中存在getSomething并不要求 SomeInterface实例的状态包含SomeClass实例。

The method could be implemented to return a newly created SomeClass , the value of a transient field, the result of calling a static method on some other class, or .... null . 该方法可以实现为返回新创建的SomeClasstransient字段的值,在某个其他类上调用static方法的结果或.... null

No, Any class just referenced within a class that is serializable is not serializable by default. 否,默认情况下,在可序列化的类中引用的任何类都不可序列化。

Ideally java should throw NotSerializableException , but since you are not getting the exception means, SomeClass extends Serializable by it's parent hierarchy somewhere. 理想情况下, java应该抛出NotSerializableException ,但是由于您没有获得异常方法,因此SomeClass通过其父层次结构在某处extends Serializable

No, SomeClass will not be Serializable just because this interface extends Serializable . 不, SomeClass不能仅因为此接口扩展了Serializable而可以Serializable Serializable

Serializable applies to the state of the object, there isn't anything here to imply that SomeClass is part of the state of SomeInterface. Serializable适用于对象的状态,此处没有任何内容暗示SomeClass是SomeInterface状态的一部分。 https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

Are you sue that when SomeClass is being Deserialized it doesn't extend a class that implements Serializable ? 您是否要求在对SomeClass进行反序列化时不扩展实现Serializable的类?

Suppose an implementation of SomeInterface just does something similar to 假设SomeInterface的实现只是做一些类似于

public class SomeInterfaceImpl implements SomeInterface {

    @Override
    public SomeClass getSomething(String someParameter) {
        return new SomeClass(someParameter);
    }
}

Why should your program fail on serializing objects of SomeInterfaceImpl when objects of SomeClass are just created on the fly ? 你的程序为什么要失败的序列化对象SomeInterfaceImpl时的对象SomeClass 对飞只是创造出来的?

Minimal Example 最小的例子

Main.java Main.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

    public static void main(String[] args) {

        try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                final ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream)) {
            final SomeInterfaceImpl someInterfaceImpl = new SomeInterfaceImpl();
            final SomeClass something1 = someInterfaceImpl.getSomething("Test");
            out.writeObject(someInterfaceImpl);

            try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                    final ObjectInputStream in = new ObjectInputStream(byteArrayInputStream)) {
                final SomeInterface someInterface = (SomeInterface) in.readObject();
                final SomeClass something2 = someInterface.getSomething("Test");

                final String someParameter1 = something1.getSomeParameter();
                System.out.println(someParameter1);

                final String someParameter2 = something2.getSomeParameter();
                System.out.println(someParameter2);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM