• ObjectInputStream和ObjectOutputStream


    package stream.object;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    /** 
     * 序列化流:
     * 		把对象按照流一样的方式;
     * 反序列化流:
     * 		把文件中的对象读取出来;
     * 
     * @author 半步疯子
     *
     * 序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输,对象 -- 流数据
     * 反序列化流:把文本文件中的流对象数据或网络中的流对象还原成对象,流数据 -- 对象
     *
     */
    public class ObjectStreamDemo01 {
    	public static void main(String[] args) throws IOException, ClassNotFoundException {
    		// 由于我们于要对对象进行序列化,所以我们要对
    		write();
    		read();
    	}
    
    	private static void read() throws IOException, ClassNotFoundException {
    		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
    		// 虽然是Object接收的,但是本质上还是Person010101的对象
    		Object obj = ois.readObject();
    		
    		ois.close();
    		// 在进行toString方法的时候,调用的还是Person010101中的toString方法
    		System.out.println(obj);
    	}
    
    	private static void write() throws IOException {
    		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
    		Person p1 = new Person("mzy", 19);
    		oos.writeObject(p1);
    		oos.close();
    	}
    }

         首先在使用ObjectInputStream和ObjectOutputStream的时候,放置在此IO中的对象,必须要实现Serializable接口!序列化接口(实现了此接口,代表我们的对象支持序列化)

           但是实现了Serializable接口之后,其中并没有实现任何方法,对于这种接口,我们称之为标记接口。

    class Person implements Serializable{
    	private String name;
    	private int age;
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	public Person() {
    
    	}
    	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;
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + "]";
    	}
    }


    首先运行一遍程序,然后注释掉前面的write方法和后面的private修饰的age,单独进行从文件中读对象到程序中。

    抛出异常:

    java.io.InvalidClassException: 

    stream.object.Person; 

    local class incompatible: // incompatible 不相容的,互相矛盾的

    stream classdesc serialVersionUID = 3743887113483319275, 

    local class serialVersionUID = 2519694131930475475

     

     

    表明两个对象不相同,因为我们其中的变量的修饰信息都修改了,对应的已经不是同一个对象了

    怎么解决?

    这里就涉及到之间,在java Swing中多次遇到的问题:
    黄色警告线:
    The serializable class Person does not declare a static final serialVersionUID field of type long
    这个警告是什么意思?

    告诉我们此序列化类,并没有一个id标识。

     每次修改.java文件的时候,.class中的id值都会改变

    (上述的修改:必须为有效修改,修改具体的代码:空格、文本注释和换行虽然也修改了,但是具体的代码并没有改变)
     
    而读取文件时,会和class文件进行匹配,如果id不同则会抛出上述的异常
     
    如果我们添加上了id标记:此类对象就可以以流的形式存储,并且可以在网络上传输
    如果我们加上了serialVersionUID 那么上面由于我们修改了类中的关键字的修饰符

    所造成的错误,就不会发生了,只要序列号相同,那么就可以了。

    class Person implements Serializable{
    	private static final long serialVersionUID = 1L;
    	String name;
    	int age;
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	public Person() {
    
    	}
    	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;
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + "]";
    	}
    }
    

    补充:用transient修饰说明这个成员变量我不想被序列化

    private transient int age;


  • 相关阅读:
    插入数据失败提示: Setting autocommit to false on JDBC Connection 自动提交失败
    MyBatis XML配置properties
    mybatis 测试输出SQL语句到控制台配置
    原创:mysql5 还原至mysql 8.0.11数据库链接配置提示错误(修改内容有三处
    idea 快捷键汇总
    maven依赖配置和依赖范围
    pom.xml 配置 收藏
    单词的提取
    UVA10815 安迪的第一个字典 Andy's First Dictionary
    UVA11054 Gergovia的酒交易 Wine trading in Gergovia
  • 原文地址:https://www.cnblogs.com/mzywucai/p/11053436.html
Copyright © 2020-2023  润新知