在java中,如何序列化未标记为可序列化的类?
在第三方库中有一个特定的类,我想序列化它。我该怎么做呢 我假设我必须编写一个方法,该方法接收类的一个对象,并使用反射来获取私有成员值。然后对于反序列化,我将使用反射将值放回原处在java中,如何序列化未标记为可序列化的类?,java,reflection,serialization,Java,Reflection,Serialization,在第三方库中有一个特定的类,我想序列化它。我该怎么做呢 我假设我必须编写一个方法,该方法接收类的一个对象,并使用反射来获取私有成员值。然后对于反序列化,我将使用反射将值放回原处 这样行吗?有没有更简单的方法 您可以只使用实现Serializable且与第三方对象具有相同字段的传输对象。让transfer对象实现一个返回原始第三方类的对象的方法,您就完成了: 伪代码: class ThirdParty{ int field1; int field2; } class Trans
这样行吗?有没有更简单的方法 您可以只使用实现Serializable且与第三方对象具有相同字段的传输对象。让transfer对象实现一个返回原始第三方类的对象的方法,您就完成了: 伪代码:
class ThirdParty{
int field1;
int field2;
}
class Transfer implements Serializable{
int field1;
int field2;
/* Constructor takes the third party object as
an argument for copying the field values.
For private fields without getters
use reflection to get the values */
Transfer (ThirdParty orig){
this.field1=orig.field1;
this.field2=orig.field2;
}
ThirdParty getAsThirdParty(){
ThirdParty copy=new ThirdParty();
copy.field1=this.field1;
copy.field2=this.field2;
return copy;
}
/* override these methods for custom serialization */
void writeObject(OutputStream sink);
void readObject(InputStream src);
}
如果您有任何特殊的成员对象,您只需确保成员被正确序列化
或者,如果第三方类不是final,您可以扩展它,让它实现可序列化,并编写您自己的writeObject和readObject方法
检查此处以获取一些序列化信息:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
很大程度上取决于第三方阶级的性质。它是最终的,它是否有一个无参数构造函数,是否可以在给定已知值的情况下构造它,还是由另一个类构造,它本身是否包含不可序列化的成员
最简单的方法是反编译类,添加一个可序列化的实现,然后重新编译它,但如果它包含不可序列化的成员,事情变得更加复杂。另一种可能的解决方案可能是在可序列化类中定义一组私有方法,该类使用第三方类的实例。这些特殊方法是序列化系统提供的特殊回调契约的一部分。这些方法将在序列化/反序列化期间调用过程 他们的签名必须是:
private void writeObject(ObjectOutputStream os) {
// your code for saving the third party variables
}
private void readObject(ObjectInputStream is) {
// your code to read the third party state, create a new ThirdParty instance,
// and assign it to your class.
}
本例进一步阐明了这一观点:
public class MyClass implements Serializable
{
transient private ThirdParty thirdPartyInstance ;
private int myClassVariable ;
private void writeObject(ObjectOutputStream oos)
{
try
{
oos.defaultWriteObject();
oos.writeInt(thirdPartyInstance.getThirdPartyVariable());
oos.writeInt(thirdPartyInstance.getFourthPartyInstance().getFourthPartyVariable());
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void readObject(ObjectInputStream ois)
{
try
{
ois.defaultReadObject(); //the call to defaultReadObject method must always be before any other code in the try block
//Reconstructing thirdPartyInstance
thirdPartyInstance =new ThirdParty(ois.readInt(),new FourthParty(ois.readInt()));
}
catch(Exception e)
{
e.printStackTrace();
}
}
MyClass(int myClassVariable, ThirdParty thirdPartyInstance)
{
this.myClassVariable=myClassVariable;
this.thirdPartyInstance=thirdPartyInstance;
}
ThirdParty getThirdPartyInstance()
{
return thirdPartyInstance;
}
int getMyClassVariable()
{
return myClassVariable;
}
public static void main(String args[])
{
FourthParty fourthPartyInstance=new FourthParty(45);
ThirdParty thirdPartyInstance=new ThirdParty(13,fourthPartyInstance);
MyClass myClassInstance=new MyClass(7,thirdPartyInstance);
System.out.println("Before: ThirdParty variable value is "+myClassInstance.getThirdPartyInstance().getThirdPartyVariable());
System.out.println("Before: FourthParty variable value is "+myClassInstance.getThirdPartyInstance().getFourthPartyInstance().getFourthPartyVariable());
System.out.println("Before: MyClass variable value is "+myClassInstance.getMyClassVariable());
try
{
FileOutputStream fios=new FileOutputStream("D://TestFileq.ser");
ObjectOutputStream oos=new ObjectOutputStream(fios);
oos.writeObject(myClassInstance);
oos.close();
FileInputStream fi = new FileInputStream("D://TestFileq.ser");
ObjectInputStream objectIn = new ObjectInputStream(fi);
MyClass myClassInst = (MyClass)objectIn.readObject();
System.out.println("After: ThirdParty variable value is "+myClassInst.getThirdPartyInstance().getThirdPartyVariable());
System.out.println("After: FourthParty variable value is "+myClassInst.getThirdPartyInstance().getFourthPartyInstance().getFourthPartyVariable());
System.out.println("After:MyClass variable value is "+myClassInst.getMyClassVariable());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class ThirdParty
{
private int thirdPartyVariable;
private FourthParty fourthPartyInstance;
ThirdParty(int thirdPartyVariable,FourthParty fourthPartyInstance)
{
this.thirdPartyVariable=thirdPartyVariable;
this.fourthPartyInstance=fourthPartyInstance;
}
int getThirdPartyVariable()
{
return thirdPartyVariable;
}
FourthParty getFourthPartyInstance()
{
return fourthPartyInstance;
}
}
class FourthParty
{
private int fourthPartyVariable;
FourthParty(int fourthPartyVariable)
{
this.fourthPartyVariable=fourthPartyVariable;
}
int getFourthPartyVariable()
{
return fourthPartyVariable;
}
}
请注意,MyClass中的第三个PartyInstance必须声明为transient,否则将发生“java.io.NotSerializableException”类型的异常。
有关更多说明,请参阅:
SCJP Sun认证的Java 6程序员,由Cathy Sierra编写,第497页您需要它与未来版本兼容吗?不需要,它不需要与未来版本兼容。您只是想保留数据吗?如果是这样,为什么不使用JAXB呢?谢谢,这看起来不错,我该如何处理私有成员变量?有没有简单的方法,或者我需要反射?是的,反射是我所知道的访问不可见字段的唯一方法/“序列化机密”链接是新链接:,