网站数据分析案例,济源网站开发,深夜的fm免费看,网站开发怎么拉客户写在开头
哈喽大家好#xff0c;在高铁上码字的感觉是真不爽啊#xff0c;小桌板又拥挤#xff0c;旁边的小朋友也比较的吵闹#xff0c;影响思绪#xff0c;但这丝毫不影响咱学习的劲头#xff01;哈哈哈#xff0c;在这喧哗的车厢中#xff0c;思考着这样的一个问题…写在开头
哈喽大家好在高铁上码字的感觉是真不爽啊小桌板又拥挤旁边的小朋友也比较的吵闹影响思绪但这丝毫不影响咱学习的劲头哈哈哈在这喧哗的车厢中思考着这样的一个问题Java中的对象是如何在各个方法或者网络中流转的呢 通过这个问题便引出了我们今天的主人公序列化与反序列化 序列化所谓的序列化就是将Java对象或数据结构转为字节序列的过程以便于存储到数据库、内存、文件系统或者网络传输。 反序列化而反序列化就是序列化的逆向操作将字节流转为Java对象的过程。 序列化的基本实现JDK
这样一看序列化是不是非常有用毋容置疑这是一个无形中都会用到的知识点那么想要在Java中实现序列化该如何做呢继续往下看。 其实只要做到2点就可以实现基本的序列化功能序列流ObjectInputStream 和 ObjectOutputStream、实现 Serializable 接口(一个标识型接口没有具体的方法仅是一种通知告诉JVM这个对象需要序列化)
【示例代码】
/*** 测试序列化反序列化* author javabuild*/
public class TestSerializable implements Serializable {private static final long serialVersionUID 5887391604554532906L;private int id;private String name;public TestSerializable(int id, String name) {this.id id;this.name name;}Overridepublic String toString() {return TestSerializable [id id , name name ];}SuppressWarnings(resource)public static void main(String[] args) throws IOException, ClassNotFoundException {//序列化ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(TestSerializable.obj));oos.writeObject(测试序列化);oos.writeObject(618);TestSerializable test new TestSerializable(1, JavaBuild);oos.writeObject(test);//反序列化ObjectInputStream ois new ObjectInputStream(new FileInputStream(TestSerializable.obj));System.out.println((String)ois.readObject());System.out.println((Integer)ois.readObject());System.out.println((TestSerializable)ois.readObject());}
}输出
测试序列化
618
TestSerializable [id1, nameJavaBuild]这种实现方式是JDK自带的方便好用易于实现代码逻辑不复杂但它有着诸多的致命缺陷导致很多大厂不会使用这种方式。 1、不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。 2、性能差相比于其他序列化框架性能更低主要原因是序列化之后的字节数组体积较大导致传输成本加大。 3、存在安全问题序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制那么攻击者即可通过构造恶意输入让反序列化产生非预期的对象在此过程中执行构造的任意代码。 序列化的其他实现方式Kryo
除了JDK自带的实现方式国内外的大厂们推出过不好的开源且好用的序列化协议比如Hessian、Kryo、Protobuf、ProtoStuff。
Hessian 一个轻量级的自定义描述的二进制 RPC 协议。Hessian 是一个比较老的序列化实现了并且同样也是跨语言的。Dubbo2.x 默认启用的序列化方式是 Hessian2 ,但是Dubbo 对 Hessian2 进行了修改不过大体结构差别不大。
Protobuf 自于 Google性能优秀支持多种语言同时还是跨平台的。就是在使用中过于繁琐因为你需要自己定义 IDL 文件和生成对应的序列化代码。这样虽然不灵活但是另一方面导致 protobuf 没有序列化漏洞的风险。不过后续谷歌推出了升级版进行了很多缺陷的优化诞生了ProtoStuff。
Kryo
目前使用最广泛好评诸多的就是具有高性能、高效率和易于使用和扩展等特点的Kryo 目前像Twitter、Groupon、Yahoo 以及多个著名开源项目如 Hive、Storm中都在使用这款序列化工具。 【示例代码】 1、引入相应的pom依赖库
!-- 引入 Kryo 序列化工具 --
dependencygroupIdcom.esotericsoftware/groupIdartifactIdkryo/artifactIdversion5.4.0/version
/dependency2、通过调用方法通过二进制实现序列化与反序列化
public class KryoDemo {public static void main(String[] args) throws FileNotFoundException {Kryo kryo new Kryo();kryo.register(KryoParam.class);KryoParam object new KryoParam(JavaBuild, 123);Output output new Output(new FileOutputStream(logs/kryo.bin));kryo.writeObject(output, object);output.close();Input input new Input(new FileInputStream(logs/kryo.bin));KryoParam object2 kryo.readObject(input, KryoParam.class);System.out.println(object2);input.close();}
}class KryoParam {private String name;private int age;public KryoParam() {}public KryoParam(String name, int age) {this.name name;this.age age;}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;}Overridepublic String toString() {return KryoParam{ name name \ , age age };}
}序列化的细节知识点
1、一般实现序列化接口后还会有个serialVersionUID它有什么作用 答SerialVersionUid 是为了序列化对象版本控制告诉 JVM 各版本反序列化时是否兼容 如果在新版本中这个值修改了新版本就不兼容旧版本反序列化时会抛出InvalidClassException异常 仅增加了一个属性希望向下兼容老版本的数据都保留就不用修改 删除了一个属性或更改了类的继承关系就不能不兼容旧数据这时应该手动更新 SerialVersionUid 2、如果有些字段不想进行序列化怎么办 答对于不想进行序列化的变量可以使用 transient 关键字修饰。transient 关键字的作用是阻止实例中那些用此关键字修饰的的变量序列化当对象被反序列化时被 transient 修饰的变量值不会被持久化和恢复。