天天看点

Java关键字、修饰符transient

1、transient关键字的使用方法

  • transient作用于成员变量上
  • transient关键字修饰的属性不会被序列化到磁盘,这个属性的生命周期仅存于调用者的内存中(特殊情况除外,见下文)
  • static 修饰的变量不管有没有transient都不会被序列化,而是直接写入jvm

示例代码:

package org.test.maven.service;

import java.io.Serializable;

public class Person implements Serializable {

    private String name;
    private transient  String pwd;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
           
package org.test.maven.service;
    
    import cn.hutool.core.util.ReflectUtil;
    
    import java.io.*;
    import java.lang.reflect.Field;
    import java.util.concurrent.ConcurrentHashMap;
    

    public class App 
    {
        public static void main( String[] args )
        {
            //测试反射
           /* Score score = new Score();
            Person person = new Person();
            person.setName("Zhangsan");
            Field[] fields = ReflectUtil.getFields(Score.class);
            for (Field field:fields) {
                if (field.getName().equals(person.getName())){
                    System.out.println(field.getName());
                    ReflectUtil.invoke(score,"set"+field.getName(),"101");
                }
            }
            System.out.println(score.getZhangsan());*/


        Person person = new Person();
        person.setName("zhangsan");
        person.setPwd("123");

        System.out.println("序列化之前,name="+person.getName()+",pwd="+person.getPwd());

        try {
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("D:/person.txt"));
            os.writeObject(person);
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream is = new ObjectInputStream(new FileInputStream("D:/person.txt"));
            person = (Person)is.readObject();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("反序列化之后,name="+person.getName()+",pwd="+person.getPwd());
    }
}


           

打印结果:

Java关键字、修饰符transient

结果说明pwd没有被序列化到磁盘

2、transient修饰的变量能被序列化的特殊情况

package org.test.maven.service;

import java.io.*;

public class Person implements Externalizable {

    private transient  String pwd;

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(pwd);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        pwd = (String) in.readObject();
    }

}
           
package org.test.maven.service;
    
    import cn.hutool.core.util.ReflectUtil;
    
    import java.io.*;
    import java.lang.reflect.Field;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class App 
    {
        public static void main( String[] args )
        {
            //测试反射
           /* Score score = new Score();
            Person person = new Person();
            person.setName("Zhangsan");
            Field[] fields = ReflectUtil.getFields(Score.class);
            for (Field field:fields) {
                if (field.getName().equals(person.getName())){
                    System.out.println(field.getName());
                    ReflectUtil.invoke(score,"set"+field.getName(),"101");
                }
            }
            System.out.println(score.getZhangsan());*/
    
    
            Person person = new Person();
            person.setPwd("123456");
    
            System.out.println("序列化之前pwd="+person.getPwd());
    
            try {
                ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("D:/person.txt"));
                os.writeObject(person);
                os.flush();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            try {
                ObjectInputStream is = new ObjectInputStream(new FileInputStream("D:/person.txt"));
                person = (Person)is.readObject();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            System.out.println("反序列化之后pwd="+person.getPwd());
        }
    }


           

打印结果:

Java关键字、修饰符transient

对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。因此本例中输出的是变量pwd初始化的值,而不是null

继续阅读