我正在尝试在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
为什么我收到此错误消息?
答案 0 :(得分:3)
可能无法序列化MemcachedClient
类中的对象。您有2个选项可以解决问题:
确保那里的所有类都实现Serializable
接口。
public class MemcachedClient {
//AnotherClass must implement Serializable too.
private AnotherClass anotherClassInstance;
}
如果其他类未实现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.
}
}
答案 1 :(得分:3)
来自Serializable
javadocs:
遍历图形时,可能会遇到不支持
Serializable
接口的对象。在这种情况下,将抛出NotSerializableException
并将标识非可序列化对象的类。
Memcached似乎隐藏了异常消息的其余部分,因此您必须自己识别不可序列化的对象。
你说values
是你自己对象的列表。我的猜测是你的对象包含的东西不是Serializable
,或者它包含包含其他的东西,而不是Serializable
。浏览列表中对象的类,确保其下的每个对象都实现Serializable
。
例如,如果A
实施Serializable
:
public class A implements Serializable {
private B b;
// ...
}
并且B
没有:
public class B { ... }
然后,使用A
(可能是Memcached库中的默认序列化程序正在执行的操作)序列化ObjectOutputStream
的任何尝试都将抛出NotSerializableException
因为其字段{{1} ,是一种非可序列化的类型,这就是你得到的。
答案 2 :(得分:1)
确保您的对象实现Serializable
(甚至是从对象引用的所有对象)
答案 3 :(得分:0)
我在序列化列表时遇到了类似的问题。我的问题原来是我正在使用List.subList,即使List只包含可序列化的项,subList返回的List也不可序列化。一个快速的解决方案是做类似
的事情List mySublist = new ArrayList().addAll(originalList.subList(...));