当前位置: 首页 > news >正文

Externalizable和Serializable序列化与关键字transient

1、Serializable序列化时不会调用默认的构造器,而Externalizable序列化时会调用默认构造器的!!!
2、Serializable:
一个对象想要被序列化,那么它的类就要实现 此接口,这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。
3、Externalizable:
他是Serializable接口的子类,有时我们不希望序列化那么多,可以使用这个接口,这个接口的writeExternal()和readExternal()方法可以指定序列化哪些属性。

4.关键字 transient[1]的作用及使用方法
In the Java programming language, transient is a keyword used as a field modifier[2]. When a field is declared transient, it would not be serialized even if the class to which it belongs is serialized. In Java, methods, classes and interfaces cannot be declared as transient, because they are never serialized.

[1]transient 美['trænziənt]英['trænziənt]adj.短暂的;转瞬即逝的;暂住的
n.暂住某地的人;过往旅客;临时工。 网络:瞬态;瞬时;暂态
[2]modifier> 美['mɑdɪ.faɪər]英['mɒdɪ.faɪə®]n.修饰语。 网络:修饰符;修饰词;

In Hibernate and other persistence systems, transient describes an object that has been instantiated, but is not associated with a Hibernate session, i. e. the object resides in memory but is not being persisted.[2]

Why does Java have transient fields?
The transient keyword in Java is used to indicate that a field should not be serialized. From the Java Language Specification, Java SE 7 Edition, Section 8.3.1.3. transient Fields: Variables may be marked transient to indicate that they are not part of the persistent state of an object.

java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String username;
    private transient String passwd;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    public static void main(String[] args) throws IOException, InterruptedException {

            User user = new User();
            user.setUsername("larry");
            user.setPasswd("password");

            System.out.println("read before Serializable: ");
            System.out.println("username: " + user.getUsername()); 
            System.err.println("password: " + user.getPasswd()); 
            try {
                ObjectOutputStream os = new ObjectOutputStream(
                        new FileOutputStream("C:/user.txt"));
                os.writeObject(user); // 将User对象写进文件
                os.flush();
                os.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                        "C:/user.txt"));
                user = (User) is.readObject(); // 从流中读取User的数据
                is.close(); 
                System.out.println("\nread after Serializable: ");
                System.out.println("username: " + user.getUsername()); 
                System.err.println("password: " + user.getPasswd());

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
}

输出结果为:

read before Serializable: 
username: larry
password: password

read after Serializable: 
username: larry
password: null

密码字段为null,说明反序列化时根本没有从文件中获取到信息
5. transient使用总结

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2)transient关键字只能修饰变量,而不能修饰方法和类。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

第三点注意(一个静态变量不管是否被transient修饰,均不能被序列化),反序列化后类中static型变量username的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的。

5. transient使用注意—被transient关键字修饰的变量不一定就是被序列化。
在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。

相关文章:

  • nmon系统监控工具
  • oracle官方文档使用
  • FlashBuilder(FB/eclipse) 打开多个无效
  • python 读写文件时,r、rt、rb、r+的区别
  • 类什么时候被加载
  • 【异构计算】OpenCL矩阵转置
  • Lazy initialization holder class模式
  • 基于HTTP的WEB服务器端口映射
  • 静态常量(static final)在class文件里是如何的呢?
  • IOS管理文件和目录
  • WIN7实现多用户远程桌面
  • Linux下rsh服务配置
  • Extjs Ext.ux.IFrame的用法 以及父子窗口间函数相互调用
  • UNIX下获取前一天后一天的日期
  • Redis持久化实践及灾难恢复模拟 [转]
  • Date型的使用
  • HTTP请求重发
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Mysql5.6主从复制
  • MySQL的数据类型
  • Python爬虫--- 1.3 BS4库的解析器
  • Sass 快速入门教程
  • Vue ES6 Jade Scss Webpack Gulp
  • 动态魔术使用DBMS_SQL
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 大数据全解:定义、价值及挑战
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​一些不规范的GTID使用场景
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (11)MSP430F5529 定时器B
  • (2)STL算法之元素计数
  • (33)STM32——485实验笔记
  • (C++17) optional的使用
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (四)汇编语言——简单程序
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)菜鸟学数据库(三)——存储过程
  • .net FrameWork简介,数组,枚举
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET的数据绑定
  • .net下的富文本编辑器FCKeditor的配置方法
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • @JSONField或@JsonProperty注解使用
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [bzoj2957]楼房重建
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解
  • [CSDN首发]鱿鱼游戏的具体玩法详细介绍