美文网首页程序员
关于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