简体   繁体   English

不可序列化对象异常

[英]Non-Serializable Object exception

I am trying to set a list of objects(serializable) in Memcached client. 我正在尝试在Memcached客户端中设置对象列表(可序列化)。 I am doing it using the set method. 我正在使用set方法。 I am getting this error message: 我收到此错误消息:

Exception occurred in target VM: Non-serializable object 目标VM中发生异常:不可序列化的对象

So it's not allowing me to set the value in the MemcachedClient object. 因此,不允许我在MemcachedClient对象中设置值。 Here's my code: 这是我的代码:

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

Why am I getting this error message? 为什么会收到此错误消息?

Maybe an object inside your MemcachedClient class can't be serialized. 也许您的MemcachedClient类中的对象无法序列化。 You have 2 options to solve the problem: 您有2种解决方案:

  1. Make sure all the classes there implement the Serializable interface. 确保那里的所有类都实现了Serializable接口。

     public class MemcachedClient { //AnotherClass must implement Serializable too. private AnotherClass anotherClassInstance; } 
  2. If the other class doesn't implement Serializable (and you can't modify those classes to make them Serializable ), then add the transient keyword so those objects won't be serialized 如果另一个类没有实现Serializable (并且您不能修改这些类以使其成为Serializable ),则添加transient关键字,以便那些对象不会被序列化

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

If you must have an instance of AnotherClass when you deserialize your MemcachedClient object, then you can write the readObject(ObjectInputStream is) to create an instance based on the needs: 如果在反序列化MemcachedClient对象时必须具有AnotherClass的实例,则可以编写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.
    }
}

Based in Brian's comment, assuming this MemcachedClient class is from a third party library and you can't modify it, you would have an scenario like described in point 2: 根据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.
    }
}

From the Serializable javadocs: 从可Serializable javadocs中:

When traversing a graph, an object may be encountered that does not support the Serializable interface. 遍历图形时,可能会遇到不支持Serializable接口的对象。 In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object. 在这种情况下,将抛出NotSerializableException并标识不可序列化对象的类。

Memcached seems to be hiding the rest of the exception message, so you'll have to identify the non-serializable object yourself. Memcached似乎隐藏了异常消息的其余部分,因此您必须自己确定不可序列化的对象。

You say that values is a list of your own object. 您说values是您自己的对象的列表。 My guess is your object holds something that isn't also Serializable , or it holds something that holds something else that isn't Serializable . 我的猜测是你的对象保存的东西是不是也Serializable ,或者其持有的东西, 认为别的东西 ,是不是Serializable Go through the class of the objects in your list and make sure that every object underneath it implements Serializable . 浏览列表中对象的类,并确保其下面的每个对象都实现Serializable

As an example, if I have A implements Serializable : 例如,如果我有A实现Serializable

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

And B doesn't: B没有:

public class B { ... }

Then any attempt to serialize A using an ObjectOutputStream (which is probably what the default serializer in the Memcached library is doing) will throw a NotSerializableException because its field, private B b , is a non-serializable type, which is what you're getting. 然后,使用ObjectOutputStream序列化A任何尝试(这可能是Memcached库中的默认序列化程序正在执行的操作)都会抛出NotSerializableException因为其字段private B b是不可序列化的类型,这就是您得到的。

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

I had a similar issue with serializing lists. 我在序列化列表时遇到类似的问题。 My issue turned out to be that I was using List.subList, and even though the List only contains serializable items, the List returned by subList was not serializable. 我的问题原来是我正在使用List.subList,即使List仅包含可序列化的项目,由subList返回的List也无法序列化。 A quick solution was to do something like 一个快速的解决方案是做类似的事情

List mySublist = new ArrayList().addAll(originalList.subList(...));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM