java中的序列化与transient关键字

    序列化和transient关键字应该属于java中较高级的话题,笔者(ymh)今天花一点时间小结一些这部分知识,希望能给初学者一些帮助。若有错误希望指出,学无止境。转载请注明出处!

什么是序列化?

      序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

如何实现序列化?

    java中要想一个类的实例能够被序列化,则该类可以实现Serializable接口,这是一个空接口,其中并没有任何需要实现的方法,仅用来在编译时让编译器标识该类的实例可被序列化,实现Serializable接口的类的实例属性将自动参与序列化过程。

   另外,java类也可以实现Externalizable接口,该接口是Serializable接口的子接口,有两个抽象方法:

实现Externalizable接口的java类需要writeExternal方法中明确指定哪些属性要参与序列化过程。

transient关键字的用途?

     transient关键字只能用于修饰变量,不能修饰方法和类。若一个类中有些属性需要被序列化,应先实现Serializable接口,而有一些属性包含敏感信息,如密码、银行卡号等,这些信息若不想被序列化,可以用transient关键字修饰。被transient修饰的属性将不参与序列化过程。

Serializable接口配合transient关键字使用案例:

public class SerializationDemo {
 
   final static class Person implements Serializable{
    private transient String id;  //transient修饰的实例属性
    private String name;
    private static int count;
    private static transient String desc; //transient修饰的类属性
    public Person(){}
    public Person(String id,String name,int count1,String desc1)
    {
     this.id=id;
     this.name=name;
     count=count1;
     desc=desc1;
    }
   }
  
 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
  System.out.println(“序列化:将对象写入文件”);
 Person person=new Person(UUID.randomUUID().toString(), “张三”, 11, “我是张三”);
 System.out.println(“transient修饰的实例属性:”+person.id);
 System.out.println(“普通实例属性:”+person.name);
 System.out.println(“普通类属性:”+person.count);
 System.out.println(“transient修饰的类属性:”+person.desc);
 //序列化
 File objectFile=new File(“f:/mm.txt”);
 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(objectFile));
 oos.writeObject(person);
 oos.close();
 person=null;
 //反序列化
 System.out.println(“反序列化:从文件中读取对象”);
 Person.count=22;
 ObjectInputStream ois=new ObjectInputStream(new FileInputStream(objectFile));
 person=(Person) ois.readObject();
 System.out.println(“transient修饰的实例属性:”+person.id);
 System.out.println(“普通实例属性:”+person.name);
 System.out.println(“普通类属性:”+person.count);
 System.out.println(“transient修饰的类属性:”+person.desc);
 ois.close();
}
  
}

输出结果:

结论:

1、对于实例属性来说,被transient修饰的实例属性将不会参与序列化。

2、对于类属性来说,无论类属性是否被transient关键字修饰,类属性都不会参加序列化过程。

可以这样理解:序列化是针对对象的操作过程,而类属性是属于类的一部分,不属于某个具体的实例,因此类属性不参与序列化。

上面测试代码也很好的佐证了这一观点,因为若类属性能够被序列化,则反序列化读取到的类属性值应该与序列化时写入的类属性值一致,但代码中反序列化前修改了类属性值,反序列化读取到的该类属性值跟着变化,说明该类属性的值并不是从反序列化的过程中读取到的,实际上是从JVM的方法区中读取的。

猜你喜欢

转载自blog.csdn.net/SomeoneMH/article/details/80773208
今日推荐