java中的Serializable接口的作用

本文详细介绍了Java对象序列化的概念及其应用场景,包括远程方法调用(RMI)、对象状态保存和恢复等。同时探讨了序列化过程中可能遇到的安全问题及解决方案,并通过具体示例展示了序列化和反序列化的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.(serializable)主要支持对象的回复,所以可以用来保存当前的程序系统状态,远程方法调用RMI(远程机器必须含有必要的.class文件,否则将掷出classNotFound   Exception),但是因为它将对象数据自动全部保存,你根本无法插手,因此对于一些敏感字段(如:password)存在安全问题。但相应有很多解决的方法,例如可以在敏感字段的声明中使用transient关键字,或者去继承externalizable接口,自己来实现readExternal()和writerExternal()方法,再或者继承serializable接口,但提供private   void   writeObject(ObjectOutputStream   s)等方法...   ...但注意static   成员的保存仍需要你的介入。

    2.1.网络传输   
       2.数据库持久   
       3.把对象保存为文件形式,以便以后还原

 

 

Object serialization的定义:
Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。 

serialization不但可以在本机做,而且可以经由网络操作(RMI)。这个好处是很大的----因为它自动屏蔽了操作系统的差异,字节顺序(用Unix下的c开发过网络编程的人应该知道这个概念)等。比如,在Window平台生成一个对象并序列化之,然后通过网络传到一台Unix机器上,然后可以在这台Unix机器上正确地重构这个对象。


Object serialization主要用来支持2种主要的特性:
1。Java的RMI(remote method invocation).RMI允许象在本机上一样操作远程机器上的对象。当发送消息给远程对象时,就需要用到serializaiton机制来发送参数和接收返回直。

2。Java的JavaBeans. Bean的状态信息通常是在设计时配置的。Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息。这也需要serializaiton机制。



二。sakulagi和rollingpig说的持久化我也说一下。
我觉得你们说的应该是英文里的persistence.但是Java语言里现在只支持lightweight persistence,就是轻量级持久化,这是通过serialization机制来实现的。

persistence是指一个对象的生命周期不由程序是否执行来决定,即使是在程序终止时这个对象也存在。它把一个serializable的对象写到磁盘(本机或其他机器上的非RAM存储器),并在程序重新调用时再读取对象到通常的RAM存储器。

为什么说Java的serialization机制实现的是lightweight persistence?因为你必须显式的序列化和反序列化程序里的对象;而不是直接由一个关键词来定义一个对象是序列化的然后由系统做相应的处理。 


下面是关于序列化的一个实例:

程序名称:SerializationDemo.java
程序主题:实现对象的序列化和反序列化
程序说明:该程序由实例化一个MyClass类的对象开始,该对象有三个实例变量,类型分别为String、int、double,是希望存储和恢复的信息。

代码内容
import java.io.*; 

public class SerializationDemo{ 

public static void main(String args[]){ 

//Object serialization 
try{ 
MyClass object1=new MyClass("Hello",-7,2.7e10); 
System.out.println("object1:"+object1); 
FileOutputStream fos=new FileOutputStream("serial"); 
ObjectOutputStream oos=new ObjectOutputStream(fos); 
oos.writeObject(object1); 
oos.flush(); 
oos.close(); 

catch(Exception e){ 
System.out.println("Exception during serialization:"+e); 
System.exit(0); 


//Object deserialization 
try{ 
MyClass object2; 
FileInputStream fis=new FileInputStream("serial"); 
ObjectInputStream ois=new ObjectInputStream(fis); 
object2=(MyClass)ois.readObject(); 
ois.close(); 
System.out.println("object2:"+object2); 

catch(Exception e){ 
System.out.println("Exception during deserialization:"+e); 
System.exit(0); 




class MyClass implements Serializable{ 
String s; 
int i; 
double d; 
public MyClass(String s,int i,double d){ 
this.s=s; 
this.i=i; 
this.d=d; 

public String toString(){ 
return "s="+s+";i="+i+";d="+d; 


程序运行结果:object1和object2的实例变量是一样的,输出如下:[code:1:a55efb5f91]object1:s=Hello;i=-7;d=2.7E10
object2:s=Hello;i=-7;d=2.7E10

 

一个小例子:

 import   java.io.ObjectInputStream;   
  import   java.io.ObjectOutputStream;   
  import   java.io.Serializable;   
    
  /**   
    *   @author   Yan   Chenyang   
    *   
    *   TODO   要更改此生成的类型注释的模板,请转至   
    *   窗口   -   首选项   -   Java   -   代码样式   -   代码模板   
    */   
  public   class     JFunction   implements   Serializable{   
    
  private   double[][]   bounds;   
  private   int   vnum;   
  private   double   result;   
  private   String   funcname;   
    
  public   JFunction(){   
  super();   
  this.bounds=null;   
  this.vnum=0;   
  this.result=0.0;   
  this.funcname=null;   
  }   
    
  public   JFunction(double[][]   bounds){   
  super();   
  this.bounds=bounds;   
  this.vnum=bounds[0].length;   
  this.result=0.0;   
  this.funcname="Function   1";   
  }   
    
  public   double   Func(double[]   var){   
    
  result=0.0;   
  for(int   i=0;i<var.length;i++)   
  result+=var[i];   
  return   result;   
  }   
    
    
  public   static   JFunction   deserialize(ObjectInputStream   oin)     
  throws   Exception{   
    
  JFunction   f=(JFunction)oin.readObject();   
                  return   f;   
    
  }   
    
  public   void   serialize(ObjectOutputStream   oout)     
  throws   Exception{   
  oout.writeObject(this);   
  }   
    
  public   String   toString(){   
  return   funcname   ;   
    
  }   
  /**   
    *   @return   返回   funcname。   
    */   
  public   String   getFuncname()   {   
  return   funcname;   
  }   
  /**   
    *   @param   funcname   要设置的   funcname。   
    */   
  public   void   setFuncname(String   funcname)   {   
  this.funcname   =   funcname;   
  }   
  }   
    
  public   class   JFunctionTest0   {   
    
  public   static   void   main(String[]   args){   
    
  double[][]   bounds={{-2.048,-2.048},{2.048,2.048}};   
  JFunction   function=new   JFunction(bounds);   
    
  Interpreter   interpreter=new   Interpreter();   
    
  try   {   
    
  double[]   x={2.15,1.00};   
  interpreter.set("var",x);   
  interpreter.source("c:/x.bsh");   
  System.out.println(interpreter.get("ret"));   
    
  }   catch   (EvalError   e)   {   
  //   TODO   自动生成   catch   块   
  e.printStackTrace();   
  }   catch   (FileNotFoundException   e)   {   
  //   TODO   自动生成   catch   块   
  e.printStackTrace();   
  }   catch   (IOException   e)   {   
  //   TODO   自动生成   catch   块   
  e.printStackTrace();   
  }   
    
    
  FileInputStream   in=null;   
                  FileOutputStream   out=null;   
                  ObjectInputStream   oin=null;   
                  ObjectOutputStream   oout=null;   
                    
                  try{   
                  out   =   new   FileOutputStream("function1.func");   
                  oout   =   new   ObjectOutputStream(out);   
                  function.serialize(oout);//序列化   
                  oout.close();   
                  oout=null;   
    
                  in   =   new   FileInputStream("function1.func");   
                  oin   =   new   ObjectInputStream(in);   
                  JFunction   tfunction   =JFunction.deserialize(oin);//反序列化   
                    
                  double[]   var={2.0,5.0};   
                    
    //               System.out.println(tfunction.Func(var));   
    //               System.out.println(tfunction);//打印结果   
    //                 
                    
                  }catch(Exception   ex){   
                  ex.printStackTrace();   
                  }finally{   
                  try   {   
                                  if   (in   !=   null)   {   
                                          in.close();   
                                  }   
                                  if   (oin   !=   null)   {   
                                          oin.close();   
                                  }   
                                  if   (out   !=   null)   {   
                                          out.close();   
                                  }   
                                  if   (oout   !=   null)   {   
    
                                          oout.close();   
                                  }   
                          }   catch   (IOException   ex1)   {   
                                  ex1.printStackTrace();   
                          }   
                  }                 
  }   
  }

 

 

 

 

 

 

 

 

序列化   用在   对象编码成字节流及从字节流编码重构对象。   
  序列化   为远程通信提供了标准的wire-level协议。   
  要使类的实例实现序列化,只要在它的声明中加入implements     
    
  java.io.Serializable   
  但是却由一些隐患   
  1   实现了序列化后,一旦发布,讲削弱改变类实现的灵活性。   
  2   增加了bug和安全漏洞的的可能性   
  3   当你的新版本发布时增加了相关的测试上的问题。   
    

  类应尽可能少的实现Serializable,接口也应该少去扩展它。

转帖地址:http://blog.youkuaiyun.com/doymm2008/article/details/4488545

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值