zoukankan      html  css  js  c++  java
  • Java基础教程——序列化

    序列化

    序列化:Serialize,将Java对象写入IO流(可以保存在数据库,文件等)
    反序列化:Deserialize,从IO流中读取并恢复Java对象。

    这么理解:序列化就是把对象封印起来,反序列化就是解封。

    对象中包含的不仅仅是字符,更多的是非字符,因此需要使用字节流。

    所有能在网上传输的对象的类都应该是可序列化的,否则程序就会出现异常。

    实现Serializable接口

    这个接口里面什么都没有,是一个标记接口,表明一个对象是可以序列化的。

    public interface Serializable {
    }
    

    transient:瞬态关键字
    |--transient变量---不参与序列化(有些变量可能属于敏感信息,如银行账户密码等)

    transient:短暂的。

    import java.io.*;
    public class 序列化1 {
    	public static void main(String[] args) throws Exception {
    		int r_w = 3;
    		if (r_w == 1) {
    			on序列化();
    		} else if (r_w == 2) {
    			on反序列化();
    		} else {
    			on序列化();
    			on反序列化();
    		}
    	}
    	private static void on序列化() throws Exception {
    		Dog _d = new Dog("狗", "金毛");
    		File f = new File("myObj.txt");
    		System.out.println("序列化:" + f.getAbsolutePath());
    		FileOutputStream fos = new FileOutputStream(f);
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    		oos.writeObject(_d);
    		oos.close();
    		fos.close();
    	}
    	private static void on反序列化() throws Exception {
    		// 前提:1.类必须可序列化,2.必须有对应的类文件
    		File f = new File("myObj.txt");
    		FileInputStream fis = new FileInputStream(f);
    		ObjectInputStream ois = new ObjectInputStream(fis);
    		Dog d = (Dog) ois.readObject();
    		System.out.println("反序列化:" + d + ": name = " + d.name);
    		ois.close();
    		fis.close();
    	}
    }
    class Dog implements Serializable {
    	private static final long serialVersionUID = 1L;
    	public Dog(String name, String type) {
    		super();
    		this.name = name;
    		this.type = type;
    	}
    	String name;
    	transient String type;
    	@Override
    	public String toString() {
    		System.out.println("type:没参与序列化");
    		return "【狗狗:name = " + name + ", type = " + type + "】";
    	}
    }
    

    运行结果:

    序列化:C:UsersAdministratorgitAh01JspJavaHtmlmyObj.txt
    type:没参与序列化
    反序列化:【狗狗:name = 狗, type = null】: name = 狗
    

    序列号: serialVersionUID
    |--修改类的定义,可能生成新的序列号
    |--|--改构造器:变
    |--|--改字段:变(包括transient字段)
    |--|--改方法体里的实现,不变;

    序列化和反序列化时的序列号如果不同,会抛出异常java.io.InvalidClassException
    可以显示声明一个固定的序列号。如:

    private static final long serialVersionUID = 1L;
    

    *另一种序列化方法:实现Externalizable接口

    Externalizable接口可以替代Serializable接口。

    需要手提供一个无参构造方法,否则在反序列化的时候会抛出异常

    java.io.InvalidClassException: ……; no valid constructor

    同时还需要定义两个方法(writeExternal()和readExternal())来控制要序列化的字段。

    下列示例,只有Dog类的实现和上例不一样,其余代码可以一样。

    package ah.externalizable;
    import java.io.*;
    public class 序列化2 {
    	public static void main(String[] args) throws Exception {
    		on序列化();
    		on反序列化();
    	}
    	private static void on序列化() throws Exception {
    		Dog _d = new Dog("狗", "金毛");
    		File f = new File("myObj.txt");
    		System.out.println(f.getAbsolutePath());
    		FileOutputStream fos = new FileOutputStream(f);
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    		oos.writeObject(_d);
    		oos.close();
    		fos.close();
    	}
    	private static void on反序列化() throws Exception {
    		File f = new File("myObj.txt");
    		FileInputStream fis = new FileInputStream(f);
    		ObjectInputStream ois = new ObjectInputStream(fis);
    		Dog d = (Dog) ois.readObject();
    		System.out.println(d + ": name = " + d.name);
    		ois.close();
    		fis.close();
    	}
    }
    class Dog implements Externalizable {
    	public Dog() {
    		// 不写空构造,读不出来(可以写)
    	}
    	public Dog(String name, String type) {
    		super();
    		this.name = name;
    		this.type = type;
    	}
    	String name;
    	String type;
    	@Override
    	public void writeExternal(ObjectOutput out) throws IOException {
    		// 不写的Field就不序列化
    		out.writeUTF(name);
    		out.writeUTF(type);
    	}
    	@Override
    	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    		// 读取顺序务必和写入顺序相同
    		name = in.readUTF();
    		type = in.readUTF();
    	}
    	@Override
    	public String toString() {
    		return "【狗狗:" + name + ", 是一只" + type + "】";
    	}
    }
    
  • 相关阅读:
    Maven常用命令:
    正向代理、反向代理、透明代理
    linux命令ps aux|grep xxx详解
    Java中Comparable和Comparator区别小结
    Java Queue之PriorityQueue
    java读写分离的实现
    CSS颜色名称和颜色值
    使用Access-Control-Allow-Origin解决跨域
    Tomcat 下启用 https:// 访问
    使用Jedis操作redis
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11179232.html
Copyright © 2011-2022 走看看