1

我正在运行 guava-14.0.1 并且我有以下代码:

public class LinearClsMalletAdaptor extends Classifier implements Serializable{
    private BiMap<Double, String> indexToLabel;
.........

classifier = new LinearClsMalletAdaptor(sp, model, hashBiMap.inverse());

分类器是我希望保留的对象,我在 Mac 上对其进行序列化和反序列化没有问题。

但是,使用我发给我朋友的同一个序列化文件,他在反序列化过程中在 Windows 机器上遇到了以下问题:

java.lang.ClassCastException: com.google.common.collect.HashBiMap cannot be cast to 

    com.google.common.collect.AbstractBiMap
           at com.google.common.collect.AbstractBiMap$Inverse.readObject(AbstractBiMap.java:390)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
           at java.util.HashMap.readObject(HashMap.java:1030)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
           at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
           at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
           at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
           at sg.edu.astar.i2r.batc.projects.getme.core.classify.hier.topdown.TopDownClassificationAnnotator.initialize(TopDownClassificationAnnotator.java:63)
           at 

如果他在自己的机器上执行序列化,则不会出现此问题。我有点困惑,HashBiMap 类是可序列化的吗?api文档说

HashBiMap 及其逆都是可序列化的。

但是这里的讨论似乎有点混乱?

4

2 回答 2

1

正如 chrylis 和 Tasm 所暗示的,问题在于 Guava 版本之间的不匹配。一个版本的 Guava 不一定能读取由另一个版本序列化的对象。(来源:Guava 主页,上面写着:“所有对象的序列化形式可能会发生变化。不要保留这些并假设它们可以被库的未来版本读取。”

您可以推断版本不同,因为HashBiMap 曾经扩展AbstractBiMap不再扩展。

(顺便说一句,您对令人困惑的讨论的链接令人困惑,因为它是关于 GWT 序列化的,它与普通的 Java 序列化是分开的。这里不涉及。那个讨论应该比现在更清楚。)

于 2013-09-30T15:59:19.330 回答
0

HashBiMap 是可序列化的

public final class HashBiMap<K, V> extends AbstractMap<K, V> implements BiMap<K, V>, Serializable

堆栈还有另一个问题。您正在尝试反序列化不同的对象。

我的意思是这个文件包含另一个类 AbstractBiMap 并且你期待 BiMap。

BiMap 与 AbstractBiMap 没有任何共同之处。

只有 EnumBiMap EnumHashBiMap 和 Inverse 扩展了 AbstractBiMap

当然,我说的是 guava 14.0.1,因此请确保在这两种情况下您都使用相同的 guava 版本。

于 2013-09-30T10:13:24.343 回答