zoukankan      html  css  js  c++  java
  • JAVA SE 基础复习-IO与序列化(3)

      Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。

      使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的"状态",即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。

      下面举一个简单的序列化的例子

    import java.io.Serializable;
    
    
    public class Stu implements Serializable,Cloneable{
        String name;
        int 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;
        }
        public String toString()
        {
            return "age="+age+"   name="+name;
        }
        public Object clone()
        {
            Stu stu=null;
            try{
                stu=(Stu)super.clone();
            }catch(CloneNotSupportedException ex)
            {
                ex.printStackTrace();
            }
            return stu;
        }
    }
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    
    public class Test {
        static class League implements Serializable,Cloneable
        {
            int level;
            Stu stu;
            public int getLevel() {
                return level;
            }
            public void setLevel(int level) {
                this.level = level;
            }
            public Stu getStu() {
                return stu;
            }
            public void setStu(Stu stu) {
                this.stu = stu;
            }
            public String toString()
            {
                return "level="+level+"    age="+stu.getAge()+"   name="+stu.getName();
            }
            
            public Object clone()
            {
                League league=null;
                try{
                    league=(League)super.clone();
                }catch(CloneNotSupportedException ex)
                {
                    ex.printStackTrace();
                }
                league.stu=(Stu)stu.clone();
                return league;
            }
        }
        public static void main(String[] args)
        {
            File file =new File("C:/league.txt");
            try{
                ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(file));
                Stu stu=new Stu();
                stu.setAge(10);
                stu.setName("ZHANG");
                League league=new League();
                league.setLevel(2);
                league.setStu(stu);
                objectOutputStream.writeObject(league);
                objectOutputStream.close();
                
                ObjectInputStream oInputStream=new ObjectInputStream(new FileInputStream(file));
                League lea=(League)oInputStream.readObject();
                oInputStream.close();
                System.out.println(lea.toString());
            }catch(IOException ex)
            {
                ex.printStackTrace();
            }catch (ClassNotFoundException ex) {
                // TODO: handle exception
                ex.printStackTrace();
            }
        }
    }

    输出:

    level=2    age=10   name=ZHANG

    我们可以看到,读取到的对象与保存的对象状态一样。这里有几点需要说明一下:

    1、基本类型 的数据可以直接序列化

    2、对象要被序列化,它的类必须要实现Serializable接口;如果一个类中有引用类型的实例变量,这个引用类型也要实现Serializable接口。比如上面 的例子中,League类中有一个Stu类型 的实例就是,要想让League的对象成功序列化,那么Stu也必须要实现Serializable接口。

    3、我们看这个语句:

    ObjectOutputStreamout  = newObjectOutputStream(new FileOutputStream(file));

    我们知道 FileOutputStream类有一个带有两个参数的重载Constructor——FileOutputStream(String,boolean),其第二个参数如果为true且String代表的文件存在,那么将把新的内容写到原来文件的末尾而非重写这个文件,这里我们不能用这个版本的构造函数,也就是说我们必须重写这个文件,否则在读取这个文件反序列化的过程中就会抛出异常,导致只有我们第一次写到这个文件中的对象可以被反序列化,之后程序就会出错。

    下面的问题是如果 我们上面 用到的Stu类没有实现Serializable接口,但是我们还想序列化League类的对象 ,怎么办。

    Java为我们提供了transient这个关键字。如果一个变量被声明成transient,那么 在序列化的过程 中,这个变量是会被无视的,即这个变量无法被序列化。

    小弟菜鸟一枚,初来乍到,有什么错误还望各位大神不吝指出,^_^。
  • 相关阅读:
    idea中svn代码冲突
    数据库表的连接(Left join , Right Join, Inner Join)用法详解
    @Param注解的用法解析
    spring @Transactional注解参数详解
    数据库的DDL、DML和DCL的区别与理解
    Mybatis:resultMap的使用总结
    Maps.newHashMap 和 new HashMap的区别
    php 个推的例子
    fidder 调接口 的 小常识
    php Memcached
  • 原文地址:https://www.cnblogs.com/maydow/p/4461264.html
Copyright © 2011-2022 走看看