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 包含的实例成员(first
和 second
)不会被强制为 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
=> 如果 A
和 B
在运行时碰巧是 Serializable
则可序列化,但不保证任何给定的 Pair
.
Pair<A, B>
/ Pair<A extends Serializable, B extends Serializable>
=> 无论类型参数如何,都永远不会序列化,因为容器本身不是 Serializable
.
这确实取决于 Serializable
的用法。如果在框架内使用它来序列化 Pair
否则会崩溃,那么你是对的。
如果这不是绝对要求并且它只是实现者可序列化的,则他们有责任确保这一点。
例如,java.util.ArrayList
也实现了 Serializable
,尽管它不要求它的成员是可序列化的。如果不是,序列化 ArrayList
将失败。
从 here 开始,JGraphT 的 Pair
class 是 Serializable
。但是此 class 包含的实例成员(first
和 second
)不会被强制为 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
=> 如果A
和B
在运行时碰巧是Serializable
则可序列化,但不保证任何给定的Pair
.Pair<A, B>
/Pair<A extends Serializable, B extends Serializable>
=> 无论类型参数如何,都永远不会序列化,因为容器本身不是Serializable
.
这确实取决于 Serializable
的用法。如果在框架内使用它来序列化 Pair
否则会崩溃,那么你是对的。
如果这不是绝对要求并且它只是实现者可序列化的,则他们有责任确保这一点。
例如,java.util.ArrayList
也实现了 Serializable
,尽管它不要求它的成员是可序列化的。如果不是,序列化 ArrayList
将失败。