Serializable in Java - JGraphT 的 Pair class - 实例成员的类型是否也应该实现 Serializable?

Serializable in Java - JGraphT's Pair class - Should the type of instance members also implement Serializable?

here 开始,JGraphT 的 Pair class 是 Serializable。但是此 class 包含的实例成员(firstsecond)不会被强制为 Serializable.

这是当前实现的样子:

public class Pair<A, B>
    implements
    Serializable

我觉得应该是这样的:

public class Pair<A extends Serializable, B extends Serializable>
    implements
    Serializable

我错过了什么吗?如果不是,那为什么不是JGraphT做的呢?

如果 A 和 B 将是您 class 的字段,那么它们应该是。

ArrayList 而非可序列化内容的示例:

测试类:

public class NonSerialClass {

    private int i;

    public NonSerialClass(int i) {
        this.i = i;
    }

    @Override
    public String toString() {
        return "NonSerialClass{" +
                "i=" + i +
                '}';
    }
}

亚军class:


        List<NonSerialClass> nonSerialClasses= new ArrayList<>();

        nonSerialClasses.add(new NonSerialClass(1));

        nonSerialClasses.add(new NonSerialClass(2));

        System.out.println("Before "+nonSerialClasses);


        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);

        oos.writeObject(nonSerialClasses);
        oos.flush();
        oos.close();


        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream oin = new ObjectInputStream(byteArrayInputStream);
        List ts = (List) oin.readObject();
        System.out.println("After "+ts);

结果将是:

Before [NonSerialClass{i=1}, NonSerialClass{i=2}]
Exception in thread "main" java.io.NotSerializableException: ru.NonSerialClass
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at java.util.ArrayList.writeObject(ArrayList.java:766)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

因为 Serializable 仅在运行时相关。

如果你想使用一对不可序列化的元素,它会起作用,除非尝试序列化会失败。但是,如果两个元素都是 Serializable,那么无论通用边界如何,它们都会序列化。

  • Pair<A extends Serializable, B extends Serializable> implements Serializable => 始终可序列化,但不能用于不可序列化 A/B
  • Pair<A, B> implements Serializable => 如果 AB 在运行时碰巧是 Serializable 则可序列化,但不保证任何给定的 Pair.
  • Pair<A, B> / Pair<A extends Serializable, B extends Serializable> => 无论类型参数如何,都永远不会序列化,因为容器本身不是 Serializable.

这确实取决于 Serializable 的用法。如果在框架内使用它来序列化 Pair 否则会崩溃,那么你是对的。

如果这不是绝对要求并且它只是实现者可序列化的,则他们有责任确保这一点。

例如,java.util.ArrayList 也实现了 Serializable,尽管它不要求它的成员是可序列化的。如果不是,序列化 ArrayList 将失败。