序列化,transient关键字使用纪要

背景: 抽空整理一下.特此纪要!

问题: 
	1. transient是什么?
	2. transient关键字能做什么?
	3. transient底层实现原理是什么?

解答:
	1. transient是什么?
		transient是java中的一个关键字.

	2. transient关键字能做什么?
		transient关键字用来修饰不需要序列化的对象属性,当对象的某个属性被transient关键字修饰后,序列化这个对象的时候,这个属性就不会被序列化.
 		
 	3. transient底层的实现原理是什么?
 		java的serialization提供了一种存储对象状态的机制.将对象的状态数据存储到磁盘,等需要的时候将其取出来.而某些业务场景对于一些特殊的属性不希望在网络上传输,
 	此时transient关键字就起到了决定性的作用,他可以将被其修饰的对象属性的生命周期限定在内存中,也就是说最终不会被写入到内存.


下面有一则用例,可以快速了解关于序列化的相关内容:
package cn.api.serialize;

import java.io.*;

/**
 * Serialize Api 序列化API
 *  Java序列化是指将java对象转化为字节序列的过程. 而Java反序列化是指将字节序列恢复为java对象的过程.从而达到网络传输,本地存储的效果.
 *
 *  transient关键字的应用
 *  序列化的两种方式:
 *      1. Serializable
 *      2. Externalizable
 *  Serializable和Externalizable的区别?
 *      Externalizable实现自Serializable.
 *      使用Externalizable序列化需要实现writeExternal()和readExternal().
 *          说明: 使用Externalizable实现序列化需要手动提供序列化对象的无参构造器.
 *      使用Externalizable序列化不需要产生序列化ID(serialVersionUID),而通过Serializable方式实现序列化时需要初始化序列化ID(serialVersionUID).
 *      相对于Serializable,使用Externalizable实现序列化其占用的内存要比Serializable要小,速度也要比Serializable要快.
 *      Serializable使用两种方式实现序列化[
 *          1. 对非transient以及非static的属性进行序列化.
 *          2. 实现writeExternal()和readExternal()进行指定属性的序列化.
 *      ] 说明: Serializable不需要提供序列化对象无参构造器的原因是,Serializable使用反射机制完成内容回复.因此没有一定要添加序列化对象的无参构造器的限制.
 * 项目中为了快速响应一般都是用Serializable来完成数据对象的序列化.有些类可以使用Externalizable接口,如: [
 *  完全控制序列的流程和逻辑.
 *  需要大量的使用序列化和反序列化操作,此时你比较关心资源和性能.(此时也可以通过第三方序列化反序列化工具来实现. 如:protobuf(Google),thrift(Facebook),AvroGeneric...)
 * ]
 */
public class SerializeApi {

    /**
     * Obj User
     */
    static class User implements Serializable{

        private final long serialVersionID = -628948656629515L;

        private String name;

        private transient int age;

        public long getSerialVersionID() {
            return serialVersionID;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }

    /**
     * Obj SerializableApiTest
     * @Explain transient修饰的非静态属性不会被序列化(静态属性在公共的方法区,因此静态变量用不用transient修饰都不会被序列化)
     */
    static class SerializableApiTest {

        private static void serializeUser() throws Exception {
            User user = new User();
            user.setName("Mir's Liu");
            user.setAge(10003);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D://template"));
            objectOutputStream.writeObject(user);
            objectOutputStream.close();
            System.out.println("transient attribute is age: " + user.getAge());
        }

        private static void deSerializeUser() throws Exception {
            File file = new File("D://template");
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            User user = (User)objectInputStream.readObject();
            System.out.println("revert transient attribute is age: " + user.getAge());
        }

        public static void main(String[] args) throws Exception{

            serializeUser();

            deSerializeUser();

        }
    }

    /**
     * Obj User1
     * @Exceplain 使用Externalizable实现序列化后,需要实现writeExternal()和readExternal()对不需要序列化的属性要手动设置(设置后即使transient修饰也是一样).
     */
    static class User1 implements Externalizable {

        /** 实现了指定参数序列化后,加不加transient都会被序列化 */
        private transient String name;

        private Integer age;

        /** 虚岁(Virtual year) */
        private Integer virtualYear;

        public User1() {}

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public Integer getVirtualYear() {
            return virtualYear;
        }

        public void setVirtualYear(Integer virtualYear) {
            this.virtualYear = virtualYear;
        }

        /**
         * 手动实现指定参数的序列化
         * @param out
         * @throws IOException
         */
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject(name);
            out.writeObject(age);
            out.writeObject(virtualYear);
        }

        /**
         * 手动实现指定参数的反序列化
         * @param in
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            name = (String) in.readObject();
            age = (Integer) in.readObject();
            virtualYear = (Integer) in.readObject();
        }

        @Override
        public String toString() {
            return "User1{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", virtualYear=" + virtualYear +
                    '}';
        }
    }

    /**
     * Obj ExternalizeAdiTest
     */
    static class ExternalizeAdiTest {

        private static void externalizeUser() throws Exception {
            User1 user = new User1();
            user.setName("Mir's Li");
            user.setAge(22);
            user.setVirtualYear(23);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D://template"));
            objectOutputStream.writeObject(user);
            objectOutputStream.close();
            System.out.println("transient attribute is name: " + user.toString());
        }

        private static void deExternalizeUser() throws Exception {
            File file = new File("D://template");
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            User1 user = (User1)objectInputStream.readObject();
            System.out.println("revert transient attribute is name: " + user.toString());
        }

        public static void main(String[] args) throws Exception{

            externalizeUser();

            deExternalizeUser();

        }
    }

    /**
     * Obj User2
     */
    static class User2 implements Serializable {

        private static transient String name;

        private int age;

        public static String getName() {
            return name;
        }

        public static void setName(String name) {
            User2.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "User2{" +
                    "age=" + age +
                    '}';
        }
    }

    static class StaticSerializableApiTest {

        private static void serializableUser2(int age) throws Exception {
            User2 user2 = new User2();
            user2.setName("Mir's Li");
            user2.setAge(age);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D://template"));
            objectOutputStream.writeObject(user2);
            objectOutputStream.close();
            System.out.println("User2: (after) " + user2.toString());
        }

        private static void deSerializableUser2() throws Exception {
            File file = new File("D://template");
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            User2 user2 = (User2)objectInputStream.readObject();
            System.out.println("User2: (end) " + user2.toString());
        }

        public static void main(String[] args) throws Exception{

            serializableUser2(12);

            deSerializableUser2();

            serializableUser2(122);

            deSerializableUser2();
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值