0

我正在尝试在 Memcached 客户端中设置对象列表(可序列化)。我正在使用 set 方法进行操作。我收到此错误消息:

目标 VM 中发生异常:不可序列化对象

所以它不允许我在MemcachedClient对象中设置值。这是我的代码:

MemcachedClient client = CacheConnectionUtil.connectToCacheServer(this.applicationEnv);
client.set(generateCacheKey(namespace, key), expireInSeconds, value);
// value is a list of objects that implements serializable

为什么我会收到此错误消息?

4

4 回答 4

4

Serializablejavadocs:

遍历图时,可能会遇到不支持Serializable接口的对象。在这种情况下,NotSerializableException将抛出并标识不可序列化对象的类。

Memcached 似乎隐藏了异常消息的其余部分,因此您必须自己识别不可序列化的对象。

你说那values是你自己的对象的列表。我的猜测是您的对象包含的东西不是也Serializable,或者它包含的东西包含其他不是的东西Serializable。遍历列表中对象的类,并确保它下面的每个对象都实现了Serializable.

例如,如果我有A工具Serializable

public class A implements Serializable {
    private B b;
    // ...
}

并且B没有:

public class B { ... }

A然后,任何使用 an进行序列化的尝试ObjectOutputStream(这可能是 Memcached 库中的默认序列化程序正在执行的操作)都会抛出 a NotSerializableException,因为它的字段 ,private B b是不可序列化的类型,这就是您所得到的。

于 2012-10-06T18:20:53.503 回答
3

也许你的MemcachedClient类中的一个对象不能被序列化。您有 2 个选项来解决问题:

  1. 确保那里的所有类都实现了Serializable接口。

    public class MemcachedClient {
    
        //AnotherClass must implement Serializable too.
        private AnotherClass anotherClassInstance;
    }
    
  2. 如果另一个类没有实现Serializable(并且你不能修改这些类来创建它们Serializable),那么添加transient关键字,这样这些对象就不会被序列化

    public class MemcachedClient {
    
        //AnotherClass doesn't implement Serializable.
        private transient AnotherClass anotherClassInstance;
    }
    

如果您AnotherClass在反序列化MemcachedClient对象时必须有一个实例,那么您可以编写根据readObject(ObjectInputStream is)需要创建一个实例:

public class MemcachedClient {

    //AnotherClass doesn't implement Serializable.
    private transient AnotherClass anotherClassInstance;

    private void writeObject(ObjectOutputStream os) throws IOException, ClassNotFoundException {
        os.defaultWriteObject();
    }

    private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
        is.defaultReadObject();
        anotherClassInstance = new AnotherClass();
        //more logic to get a consistant AnotherClass instance.
    }
}

根据 Brian 的评论,假设此类MemcachedClient来自第三方库并且您无法修改它,您将遇到第 2 点中描述的场景:

public class MyClass {

    //MemcachedClient can't be modified and doesn't implement Serializable interface
    //the only solution would be using the transient modifier
    private transient MemcachedClient memcachedClient;

    //MyClass attributes and methods...

    //If you need to keep a MemcachedClient instance when deserializing the object
    //just write the readObject method

    private void writeObject(ObjectOutputStream os) throws IOException, ClassNotFoundException {
        os.defaultWriteObject();
    }

    private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
        is.defaultReadObject();
        memcachedClient= new MemcachedClient();
        //more logic to get a consistant MemcachedClient instance.
    }
}
于 2012-10-06T18:02:20.327 回答
1

确保您的对象实现Serializable(甚至是从您的对象引用的所有对象)

于 2012-10-06T17:56:00.283 回答
0

我在序列化列表时遇到了类似的问题。我的问题原来是我使用的是 List.subList,即使 List 只包含可序列化的项目,subList 返回的 List 也不是可序列化的。一个快速的解决方案是做类似的事情

List mySublist = new ArrayList().addAll(originalList.subList(...));
于 2013-11-25T11:47:45.710 回答