• 关于Java序列化的一些高级用法


    该说的都在注释中说完了。直接给程序吧。

    package test.javaPuzzler.p5;
    
    import java.io.*;
    import java.io.ObjectInputStream.GetField;
    import java.io.ObjectOutputStream.PutField;
    
    // 转载请注明来自http://blog.csdn.net/sunxing007
    // 一个类实现Serializable来表明自己可以被序列化;
    // 有一点需要特别注意的是:
    // 如果子类实现了Serializable,而父类没有,则父类不会被序列化;
    public class SerializableObject implements Serializable {
    
    	// 生成的序列化版本号会因为编译环境,声明的类名,成员名称和数量的变化而不同;
    	// 也就是说这个版本号一定程度上记录着类的定义性的信息,如果类的定义变化了,最好重新生成版本号;
    	// 如果新的代码使用了旧的版本号,则在反序列化的时候,可以兼容读取旧类的字节码而不会报错;
    	private static final long serialVersionUID = 9038542591452547920L;
    
    	public String name;
    	public String password;
    	// 如果你不希望某个非静态成员被序列化,可以用transient来修饰它;
    	public transient int age;
    	// 静态成员不会被序列化,因为序列化保存的是实例的状态信息,而静态成员是类的状态信息;
    	public static int version = 1;
    
    	public SerializableObject(String name, String password) {
    		this.name = name;
    		this.password = password;
    	}
    
    	// 每个类可以写一个writeObject方法,这个方法将会负责该类自身的序列化过程;
    	// 比如对于敏感信息如password,可以加密之后再序列化;
    	// 这个过程需要用到PutField,它可以指定哪些域会被序列化,怎么序列化(比如加密);
    	// 如果没有定义这个方法,将会调用ObjectOutputStream 的 defaultWriteObject;
    
    	// 你可以注释掉readObject方法,然后运行测试用例来测试密码是否被加密;
    	private void writeObject(ObjectOutputStream out) throws IOException {
    		PutField putFields = out.putFields();
    		putFields.put("name", name);
    		// 模拟加密密码
    		putFields.put("password", "thePassword:" + password);
    		out.writeFields();
    	}
    
    	// 每个类可以写一个readObject方法,该方法负责该类自身的反序列化过程;
    	// 比如对序列化时加密后的密码解密;
    	// 这个过程需要用到GetField,他可以具体地读取每个域;或执行解密动作等等;
    	// 如果没有定义这个方法,将会调用ObjectInputStream 的 defaultReadObject;
    	private void readObject(ObjectInputStream in)
    			throws ClassNotFoundException, IOException {
    		GetField readFields = in.readFields();
    		// 读取到成员的值之后,直接赋给该域,即完成该域的反序列化;
    		name = (String) readFields.get("name", "defaultName");
    		// 模拟解密密码
    		String encPassword = (String) readFields.get("password",
    				"thePassword:defaultValue");
    		password = encPassword.split(":")[1];
    	}
    
    	// 序列化
    	// 主要用到ObjectOutputStream;
    	public void save() throws IOException {
    		FileOutputStream fout = new FileOutputStream("e:\\obj");
    		ObjectOutputStream oout = new ObjectOutputStream(fout);
    		oout.writeObject(this);
    		oout.close();
    		fout.close();
    	}
    
    	// 反序列化
    	// 主要用到ObjectInputStream
    	public static SerializableObject load() throws IOException,
    			ClassNotFoundException {
    		FileInputStream fin = new FileInputStream("e:\\obj");
    		ObjectInputStream oin = new ObjectInputStream(fin);
    		Object o = oin.readObject();
    		return (SerializableObject) o;
    
    	}
    
    	@Override
    	public String toString() {
    		return "name: " + name + ", password: " + password;
    	}
    
    	// 测试用例
    	public static void main(String[] args) throws IOException,
    			ClassNotFoundException {
    		SerializableObject so = new SerializableObject(
    				"http://blog.csdn.net/sunxing007", "123456");
    		so.save();
    		System.out.println(so);
    		System.out.println(SerializableObject.load());
    	}
    
    }
    


    [转载请注明来自http://blog.csdn.net/sunxing007]

  • 相关阅读:
    [LeetCode] 310. Minimum Height Trees
    [LeetCode] 722. Remove Comments
    [LeetCode] 243, 244, 245. Shortest Word Distance I, II, III
    [LeetCode] 939. Minimum Area Rectangle
    [LeetCode] 135. Candy
    [LeetCode] 1395. Count Number of Teams
    [LeetCode] 673. Number of Longest Increasing Subsequence
    [LeetCode] 724. Find Pivot Index
    [LeetCode] 1219. Path with Maximum Gold
    [LeetCode] 849. Maximize Distance to Closest Person
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3138803.html
Copyright © 2020-2023  润新知