2019-06-18 13:24:03 1198浏览
今天千锋扣丁学堂Java培训老师给大家分享一篇关于深入了解java序列化的详细介绍,首先将Java对象序列化为二进制文件的Java序列化技术是Java系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现Serializable接口,使用ObjectInputStream和ObjectOutputStream进行对象的读写。然而在有些情况下,光知道这些还远远不够,文章列举了笔者遇到的一些真实情境,它们与Java序列化相关,通过分析情境出现的原因,使读者轻松牢记Java序列化中的一些高级认识。
package com.inout; import java.io.Serializable; public class A implements Serializable { private static final long serialVersionUID = 1L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } package com.inout; import java.io.Serializable; public class A implements Serializable { private static final long serialVersionUID = 2L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Test implements Serializable { private static final long serialVersionUID = 1L; public static int staticVar = 5; public static void main(String[] args) { try { //初始时staticVar为5 ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("result.obj")); out.writeObject(new Test()); out.close(); //序列化后修改为10 Test.staticVar = 10; ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); Test t = (Test) oin.readObject(); oin.close(); //再读取,通过t.staticVar打印新的值 System.out.println(t.staticVar); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
private static final long serialVersionUID = 1L; private String password = "pass"; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } private void writeObject(ObjectOutputStream out) { try { PutField putFields = out.putFields(); System.out.println("原密码:" + password); password = "encryption";//模拟加密 putFields.put("password", password); System.out.println("加密后的密码" + password); out.writeFields(); } catch (IOException e) { e.printStackTrace(); } } private void readObject(ObjectInputStream in) { try { GetField readFields = in.readFields(); Object object = readFields.get("password", ""); System.out.println("要解密的字符串:" + object.toString()); password = "pass";//模拟解密,需要获得本地的密钥 } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { try { ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("result.obj")); out.writeObject(new Test()); out.close(); ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); Test t = (Test) oin.readObject(); System.out.println("解密后的字符串:" + t.getPassword()); oin.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
在清单3的writeObject方法中,对密码进行了加密,在readObject中则对password进行解密,只有拥有密钥的客户端,才可以正确的解析出密码,确保了数据的安全。执行控制台输出如图所示。
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("result.obj")); Test test = new Test(); //试图将对象两次写入文件 out.writeObject(test); out.flush(); System.out.println(new File("result.obj").length()); out.writeObject(test); out.close(); System.out.println(new File("result.obj").length()); ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); //从文件依次读出两个文件 Test t1 = (Test) oin.readObject(); Test t2 = (Test) oin.readObject(); oin.close(); //判断两个引用是否指向同一个对象 System.out.println(t1 == t2);
31 36 true
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj")); Test test = new Test(); test.i = 1; out.writeObject(test); out.flush(); test.i = 2; out.writeObject(test); out.close(); ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); Test t1 = (Test) oin.readObject(); Test t2 = (Test) oin.readObject(); System.out.println(t1.i); System.out.println(t2.i);
【关注微信公众号获取更多学习资料】 【扫码进入JavaEE/微服务VIP免费公开课】