假设我有
public interface General extends Serializable {
...
}
和
public class Specific implements General {
...
}
我可以ArrayList<Specific>
通过发送和类型的对象ObjectOutputStream
并通过转换为反序列化它List<General>
吗?那会奏效吗?如果没有,我该怎么做?
假设我有
public interface General extends Serializable {
...
}
和
public class Specific implements General {
...
}
我可以ArrayList<Specific>
通过发送和类型的对象ObjectOutputStream
并通过转换为反序列化它List<General>
吗?那会奏效吗?如果没有,我该怎么做?
我自己没有尝试过,但我认为它会起作用——看看ArrayList.readObject()/writeObject()
。将writeObject()
写入Specific
对象,并且readObject()
应该能够将它们作为 的实例读回Specific
,并且反序列化列表中的每个元素都是一个General
引用,因此应该没问题。
ArrayList 是可序列化的,根据 javadocs(许多 Collection 类是,只要它们包含的对象是),只要泛型类型是可序列化的,序列化端就可以工作 - 您将序列化并读回一个对象一个数组列表
这是一个不确定的演员阵容。一般来说,它会被认为是不安全的。如果你有一个
List<Specific>
您将无法将其投射到
List<Generic>
它们在逻辑上不是一回事(即使它们在运行时确实是)。事实上,像这样在程序中直接强制转换是有问题的,因为这样是有效的:
List<Specific> specific = ...;
List<Generic> generic = (List<Generic>) specific;
generic.add(new OtherImplExtendingGeneric());
specific.get(specific.length() -1).methodOnlyOnSpecific(); // Kersplode
但是您将它视为一个对象,并且您没有对其他类型的其他引用,因此它会起作用。它不会阻止你这样做。它将在技术上产生预期的结果。这可能是有原因的,但它肯定会让我在代码审查中大吃一惊。
为什么需要转换泛型类型?
是的,它有效:
out.writeObject(list);
和
List<General> list = (List<General>)in.readObject();
泛型类型和“普通”数据类型之间的区别在于泛型仅对编译器可见,而不是在运行时可见。这意味着带有泛型的强制转换不是 100% 安全的,因为在运行时List<A>
和List<B>
是相同的。
但是,如果您确定该列表是一个列表,General
我认为这里没有问题。