如何将包含不可序列化字段的java对象序列化为字节数组,并反序列化该数组以获取原始对象
大家好,我最近在java项目中遇到了序列化和反序列化问题。我有一个类的对象,包含其他对象作为字段 我想将对象的状态存储到字节数组中,然后反序列化字节数组并返回原始对象。但是,组成对象字段的对象是不可序列化的(来自第三方库),因此必须首先声明它们为瞬态的 现在,我的对象被序列化和反序列化,但正如预期的那样,由于我前面提到的瞬态声明,它的字段为空。我尝试在序列化类中本地创建所有元素,并将原始元素的值分配给它们,然后继续此过程,但没有任何区别。我在下面引用了我的部分代码,有什么想法吗?事先谢谢:) 这是我的对象的类及其字段如何将包含不可序列化字段的java对象序列化为字节数组,并反序列化该数组以获取原始对象,java,arrays,serialization,deserialization,notserializableexception,Java,Arrays,Serialization,Deserialization,Notserializableexception,大家好,我最近在java项目中遇到了序列化和反序列化问题。我有一个类的对象,包含其他对象作为字段 我想将对象的状态存储到字节数组中,然后反序列化字节数组并返回原始对象。但是,组成对象字段的对象是不可序列化的(来自第三方库),因此必须首先声明它们为瞬态的 现在,我的对象被序列化和反序列化,但正如预期的那样,由于我前面提到的瞬态声明,它的字段为空。我尝试在序列化类中本地创建所有元素,并将原始元素的值分配给它们,然后继续此过程,但没有任何区别。我在下面引用了我的部分代码,有什么想法吗?事先谢谢:) 这
public class AbePublicKey implements java.io.Serializable{
private static final long serialVersionUID = 7526472295622776147L;
public transient Element g;
public transient Element h;
public transient Element f;
public transient Element e_g_g_hat_alpha;
}
这是我的序列化程序函数
public byte[] PublicKeytoByteArray(AbePublicKey publickey) throws IOException {
KeyAuthority keyauthority = new KeyAuthority();
byte[] bytes = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
publickey.setElements(g, h, f, e_g_g_hat_alpha);
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(publickey);
oos.flush();
bytes = bos.toByteArray();
} finally {
if (oos != null)
oos.close();
}
if (bos != null) {
bos.close();
}
}
return bytes;
}
这是我的反序列化函数
public static AbePublicKey PublicKeyBytestoObject(byte[] publickeybytes) throws IOException, ClassNotFoundException {
AbePublicKey obj = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bis = new ByteArrayInputStream(publickeybytes);
ois = new ObjectInputStream(bis);
obj = (AbePublicKey) ois.readObject();
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
return obj;
}
如果要控制对象的序列化方式,请实现Externalizable接口以及关联的readExternal和writeExternal方法。这使您能够完全控制对象的序列化方式
显然,不能序列化包含不可序列化字段的类。但是您可能可以自己编写足够的数据来重新创建对象。如果您能够将所需的值复制到类中新的可序列化CustomElement对象中,那么应该会有所不同。使用复制构造函数(如果可用),或者如果有足够的可用信息,甚至可以使用反射。您可以将
元素
字段包装在一个可序列化的类中,以便编写它们。此解决方案假定您能够在阅读元素后调用必要的setter或构造函数来重新创建该元素
以下是一个例子:
非常基本的元素,不可序列化
public class Element {
private String value;
public Element(){
value = null;
}
public Element(String value){
setValue(value);
}
public void setValue(String value){
this.value = value;
}
public String getValue(){
return value;
}
}
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SerializableElement implements Serializable{
// Generated ID
private static final long serialVersionUID = -6751688345227423403L;
private transient Element element;
public SerializableElement(Element el)
{
element = el;
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
out.writeObject(element.getValue());
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
String elementValue = (String)in.readObject();
element = new Element(elementValue);
}
private void readObjectNoData()
throws ObjectStreamException{
element = null;
}
public Element getElement(){
return element;
}
}
现在是一个非常基本的包装类,它是可序列化的
public class Element {
private String value;
public Element(){
value = null;
}
public Element(String value){
setValue(value);
}
public void setValue(String value){
this.value = value;
}
public String getValue(){
return value;
}
}
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SerializableElement implements Serializable{
// Generated ID
private static final long serialVersionUID = -6751688345227423403L;
private transient Element element;
public SerializableElement(Element el)
{
element = el;
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
out.writeObject(element.getValue());
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
String elementValue = (String)in.readObject();
element = new Element(elementValue);
}
private void readObjectNoData()
throws ObjectStreamException{
element = null;
}
public Element getElement(){
return element;
}
}
最后是一个运行序列化和反序列化逻辑的主类(根据您发布的内容稍微修改):
可能重复感谢提示!