簡體   English   中英

不可序列化對象異常

[英]Non-Serializable Object exception

我正在嘗試在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

為什么會收到此錯誤消息?

也許您的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; } 

如果在反序列化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.
    }
}

根據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.
    }
}

從可Serializable javadocs中:

遍歷圖形時,可能會遇到不支持Serializable接口的對象。 在這種情況下,將拋出NotSerializableException並標識不可序列化對象的類。

Memcached似乎隱藏了異常消息的其余部分,因此您必須自己確定不可序列化的對象。

您說values是您自己的對象的列表。 我的猜測是你的對象保存的東西是不是也Serializable ,或者其持有的東西, 認為別的東西 ,是不是Serializable 瀏覽列表中對象的類,並確保其下面的每個對象都實現Serializable

例如,如果我有A實現Serializable

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

B沒有:

public class B { ... }

然后,使用ObjectOutputStream序列化A任何嘗試(這可能是Memcached庫中的默認序列化程序正在執行的操作)都會拋出NotSerializableException因為其字段private B b是不可序列化的類型,這就是您得到的。

確保您的對象實現可Serializable (甚至從對象引用的所有對象)

我在序列化列表時遇到類似的問題。 我的問題原來是我正在使用List.subList,即使List僅包含可序列化的項目,由subList返回的List也無法序列化。 一個快速的解決方案是做類似的事情

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM