美文网首页程序员
关于transient的理解

关于transient的理解

作者: Mr_Rains | 来源:发表于2017-09-07 14:43 被阅读0次

我们知道在java中,我们要将一个对象序列化以后,再将其反序列化以后就可以得到之前序列化之前的内容.但是,假如我们有时并不是想让某个类的所有的成员变量都要被序列化,那怎么办呢?其中一种方法是使用静态static来修饰,另外一种就是今天要说的transient这个关键字.

  • transient关键字能实现什么?
    当对象被序列化时(写入字节序列到目标文件)时,transient阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行,这样的实例变量值不会被持久化和恢复。例如,当反序列化对象——数据流(例如,文件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引用的输入流无法被打开。

  • 如何使用transient?
    下面是一个小小的例子来简要说明一下,就直接上代码了:

      package com.rain.trainsent;
    
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutputStream;
      import java.io.Serializable;
      import java.util.ArrayList;
    
      public class TestTransient {
    
          public static void main(String[] args) throws FileNotFoundException, IOException {
              // TODO Auto-generated method stub
      
              Student s = new Student("zhangsan",12);
              System.out.println(s.toString());
              //序列化 被设置为transient 没有被序列化进去
              ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("student.txt"));
              o.writeObject(s);
              o.close();
    
              //重新读取序列化的内容
              ObjectInputStream in = new ObjectInputStream(new FileInputStream("student.txt"));
      
              try {
                  Student stu = (Student) in.readObject();
                  System.out.println(stu.toString());
              } catch (ClassNotFoundException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
      }
      class Student implements Serializable{
          private transient String name;
          private  int id;
          public Student(String name, int id) {
              super();
              this.name = name;
              this.id = id;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getId() {
              return id;
          }
          public void setId(int id) {
              this.id = id;
          }
          @Override
          public String toString() {
              return "Student [name=" + name + ", id=" + id + "]";
        }
    
      }
    

    可以看到,当我们将这个类的name属性用transient修饰后,当我们将其序列化以后,反序列化的时候就得不到它之前的值了

  • transient使用细节——被transient关键字修饰的变量真的不能被序列化吗?
    看一下下面的一个例子:

      package com.rain.test;
      import java.io.Externalizable;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectInput;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutput;
      import java.io.ObjectOutputStream;
    
      public class TestTransient implements Externalizable {
    
          private transient String content="我会被序列化的,不管我有没有被transient修饰";
    
          public static void main(String[] args) throws ClassNotFoundException, IOException {
              TestTransient et = new TestTransient();
      
              ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                      new File("test")));
              out.writeObject(et);
    
              ObjectInput in = new ObjectInputStream(new FileInputStream(new File(
                    "test")));
              et = (TestTransient) in.readObject();
              System.out.println(et.content);
    
              out.close();
              in.close();
    
          }
    
          @Override
          public void writeExternal(ObjectOutput out) throws IOException {
              out.writeObject(content);
          }
    
          @Override
          public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
              content = (String) in.readObject();
      
        }
    
    }
    

    我们知道在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关.因此第二个例子输出的是变量content初始化的内容,而不是null.以上是个人对关键字transient的一些理解,希望能起到抛砖引玉的作用.

相关文章

网友评论

    本文标题:关于transient的理解

    本文链接:https://www.haomeiwen.com/subject/dndijxtx.html