`
xiebh
  • 浏览: 604302 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

Java Serializable的理解

阅读更多
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

Java的"对象序列化"能让你将一个实现了Serializable接口的对象转换成一组byte,这样日后要用这个对象时候,你就能把这些byte数据恢复出来,并据此重新构建那个对象了。

要想序列化对象,你必须先创建一个OutputStream,然后把它嵌进ObjectOutputStream。这时,你就能用writeObject( )方法把对象写入OutputStream了。

writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以还原它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。

  读的时候,你得把 InputStream嵌到ObjectInputStream里面,然后再调用readObject( )方法。不过这样读出来的,只是一个Object的reference,因此在用之前,还得先下传。readObject 方法负责从流中读取并还原类字段。它可以调用 in.defaultReadObject 来调用默认机制,以还原对象的非静态和非瞬态字段。

defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应命名字段保存的对象的字段。这用于处理类发展后需要添加新字段的情形。该方法本身不需要涉及属于其超类或 子类的状态。状态是通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。

看一个列子:

import  java.io. *

class  tree  implements  java.io.Serializable 
    
public  tree left; 
    
public  tree right; 
    
public   int  id; 
    
public   int  level; 

    
private   static   int  count  =   0

    
public  tree( int  depth) 
        id 
=  count ++
        level 
=  depth; 
        
if  (depth  >   0
            left 
=   new  tree(depth - 1 ); 
            right 
=   new  tree(depth - 1 ); 
        }
 
    }
 

    
public   void  print( int  levels) 
        
for  ( int  i  =   0 ; i  <  level; i ++
            System.out.print(
"    " ); 
        System.out.println(
" node  "   +  id); 

        
if  (level  <=  levels  &&  left  !=   null
            left.print(levels); 

        
if  (level  <=  levels  &&  right  !=   null
            right.print(levels); 
    }
 


    
public   static   void  main (String argv[]) 

        
try  
            
/**/ /*  创建一个文件写入序列化树。  */  
            FileOutputStream ostream 
=   new  FileOutputStream( " tree.tmp " ); 
            
/**/ /*  创建输出流  */  
            ObjectOutputStream p 
=   new  ObjectOutputStream(ostream); 

            
/**/ /*  创建一个二层的树。  */  
            tree base 
=   new  tree( 2 ); 

            p.writeObject(base); 
//  将树写入流中。 
            p.writeObject( " LiLy is 惠止南国 " );
            p.flush(); 
            ostream.close();    
//  关闭文件。 

            
/**/ /*  打开文件并设置成从中读取对象。  */  
            FileInputStream istream 
=   new  FileInputStream( " tree.tmp " ); 
            ObjectInputStream q 
=   new  ObjectInputStream(istream); 

            
/**/ /*  读取树对象,以及所有子树  */  
            tree new_tree 
=  (tree)q.readObject(); 

            new_tree.print(
2 );   //  打印出树形结构的最上面 2级 
            String name  =  (String)q.readObject();
            System.out.println(
" \n " + name);
        }
  catch  (Exception ex) 
            ex.printStackTrace(); 
        }
 
    }
 
}
 

 

  最后结果如下:

    node 0
  node 1
node 2
node 3
  node 4
node 5
node 6

LiLy is 惠止南国

  可以看到,在序列化的时候,writeObject与readObject之间的先后顺序。readObject将最先write的object read出来。用数据结构的术语来讲就姑且称之为先进先出吧!

在序列化时,有几点要注意的:
1:当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
2:如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
3:如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化

还有我们对某个对象进行序列化时候,往往对整个对象全部序列化了,比如说类里有些数据比较敏感,不希望序列化,一个方法可以用transient来标识,另一个方法我们可以在类里重写

private   void  readObject(java.io.ObjectInputStream stream)
     
throws  IOException, ClassNotFoundException;
 
private   void  writeObject(java.io.ObjectOutputStream stream)
     
throws  IOException

  这二个方法!
  示例:

import  java.io. * ;

class  ObjectSerialTest
{
    
public   static   void  main(String[] args)  throws  Exception
    
{
        Employee e1
= new  Employee( " zhangsan " , 25 , 3000.50 );
        Employee e2
= new  Employee( " lisi " , 24 , 3200.40 );
        Employee e3
= new  Employee( " wangwu " , 27 , 3800.55 );
        
        FileOutputStream fos
= new  FileOutputStream( " employee.txt " );
        ObjectOutputStream oos
= new  ObjectOutputStream(fos);
        oos.writeObject(e1);
        oos.writeObject(e2);
        oos.writeObject(e3);
        oos.close();
        
        FileInputStream fis
= new  FileInputStream( " employee.txt " );
        ObjectInputStream ois
= new  ObjectInputStream(fis);
        Employee e;
        
for ( int  i = 0 ;i < 3 ;i ++ )
        
{
            e
= (Employee)ois.readObject();
            System.out.println(e.name
+ " : " + e.age + " : " + e.salary);
        }

        ois.close();
    }

}


class  Employee  implements  Serializable
{
    String name;
    
int  age;
    
double  salary;
    
transient  Thread t = new  Thread();
    
public  Employee(String name, int  age, double  salary)
    
{
        
this .name = name;
        
this .age = age;
        
this .salary = salary;
    }

    
private   void  writeObject(java.io.ObjectOutputStream oos)  throws  IOException
    
{
        oos.writeInt(age);
        oos.writeUTF(name);
        System.out.println(
" Write Object " );
    }

    
private   void  readObject(java.io.ObjectInputStream ois)  throws  IOException
    
{
        age
= ois.readInt();
        name
= ois.readUTF();
        System.out.println(
" Read Object " );
    }


}
分享到:
评论

相关推荐

    Java_Serializable(序列化)的理解和总结

    Java_Serializable(序列化) 的理解和总结

    JAVA高级程序设计测试题含答案.docx

    第3题 【单选题】【2.00分】【概念理解】 java中用于创建文件对象的类是 [单选题] * JAVA高级程序设计测试题含答案全文共43页,当前为第1页。 A. File(正确答案) B. Object C. Thread D. Frame E. 示例 第4题 【单选...

    Java面试题.docx

    16、说说你对Java反射的理解 17、说说你对Java注解的理解 18、Java中String的了解 19、String为什么要设计成不可变的? 20、Object类的equal和hashCode方法重写,为什么? 21-40题 21、List,Set,Map的区别 26...

    Java 高级特性.doc

    以上的一些程序代码均为张老师课堂即兴发挥所写,也可以看出,张老师对JAVA特性的深刻理解能力!现在说说我对这些程序代码的理解,说实话,才开始听张老师讲的时候,我感觉很模糊的,但是当我真正理解了之后,觉得...

    Java面试宝典-经典

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    Java面试宝典2010版

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    java面试题大全(2012版)

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    学生成绩管理系统

    巩固和加深学生对高级语言程序设计课程的基本知识的理解和掌握,掌握java语言编程和程序调试的基本技能,利用java语言进行基本的软件设计,提高运用java语言解决实际问题的能力。 2、内容要求 实现学生成绩的管理...

    Java面试的10个问题(含参考答案).docx

    Java面试的10个问题 请你简述Java框架集合相关知识。 在SQL中什么是事务? 什么是DDL、DML、DCL TCL? java中实现多态的机制是什么?...解释一下java.io.Serializable接口。 Error和Exception的区别。

    最新Java面试宝典pdf版

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    java面试宝典2012

    或者请解释Serializable接口的作用。 56 75、描述一下JVM加载class文件的原理机制? 56 76、heap和stack有什么区别。 57 77、GC是什么? 为什么要有GC? 57 78、垃圾回收的优点和原理。并考虑2种回收机制。 57 79、垃圾...

    Java面试笔试资料大全

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    JAVA面试宝典2010

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    Java面试宝典2012新版

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾...

    Java面试宝典2012版

    或者请解释Serializable接口的作用。 51 75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79...

    基于Java的XML解析与反射设计模式.doc

    xstream可以完美转换xml,与以往的解析xml工具dom相比,xstream是一个易用的、开源 的库,使用起来简单、小巧,容易理解,可以轻易的将java对象和xml文档相互转换,而 且可以修改某个特定的属性和节点名称。...

    Java中的序列化与反序列化.pdf

    Serializable接口和Externalizable接口实现序列化和反序列化

Global site tag (gtag.js) - Google Analytics