5.24Java对象流

5.24Java对象流

之前所学的是数据流,操作的是基本数据类型和字符串

Java对象流的特点

  • 不仅能操作基本数据类型还能操作各种各样的对象

ObjectOutputStream是序列化--->对象输出流--->Serialization
  • ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。

  • 只有支持java.io.Serializable接口的对象才能写入流中。

  • 与原有的write方法多了一个writeObject方法

ObjectInpuStream是反序列化--->对象输入流--->Deserialization
  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。

  • 里面有reade方法多了一个readeObejct方法--->需要对其进行转化

图片内容说明:

对象--->输出--->字节流--->存储--->文件、数据库、内存中--->然后将序列化后的对象还原成原来的对象

过程

  • 先写出后读取

  • 读取的顺序和写出的顺序一致

  • 不是所有的对象都可以序列化--->必须给一个标识告诉虚拟机该对象可以序列化--->serializable接口当中的内容(该接口是一个空接口)--->如果是自定义的类想实现序列化必须实现该接口

序列化必须注意Serializable接口,同时需要加判断

package iostudy.data;

import java.io.*;
import java.util.Date;

/**
* 对象流:
* 1、写出后读取
* 2、读取顺序与写出保持一致
* 3、不是所有的对象都可以序列化,必须实现接口Serializable
* ObjectOutputStream--->序列化
* ObjectInputStream--->反序列化
* @since JDK 1.8
* @date 2021/5/24
* @author Lucifer
*/
public class ObjectTest {
   public static void main(String[] args) throws IOException, ClassNotFoundException {
       //DataOutputStream--->保存了数据类型写入输出流当中--->构造器需要一个字节流,内部要有一个最底层的节点流
       /*
       底层节点流
       1、File
       2、ByteArray--->新增的方法toByteArray意味着不需要多态
       !!!任何数据都可以转成字节数组
        */
       //写出
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       ObjectOutputStream oos = new ObjectOutputStream(
               new BufferedOutputStream(
                       baos
              )
      );
       //操作数据类型 + 数据
       oos.writeUTF("唔系嫡系");
       oos.writeInt(21);
       oos.writeBoolean(false);
       oos.writeChar('c');
       //写入对象
       oos.writeObject("玛卡巴卡");
       oos.writeObject(new Date());
       Employee emp = new Employee("码云", 5000, 50);
       oos.writeObject(emp);
       /*
       注意
       无论是String还是Date它们都已经再类中实现了接口Serializable
        */
       //刷新一下
       oos.flush();
       /*
       上面的操作是将那些数据类型的数据写入到字节数组缓冲流当中
        */
       //存放数据的字节数组
       byte[] datas = baos.toByteArray();

       //读取
       ObjectInputStream ois = new ObjectInputStream(
               //最外层装饰器
               new BufferedInputStream(
                       new ByteArrayInputStream(
                               datas
                      )
              )
      );
       /*
       有里到外
       1、节点流
       2、节点数据类型转换流
       3、装饰流
        */
       //按照写入的数据类型读取
       String msg = ois.readUTF();
       int age = ois.readInt();
       boolean flag = ois.readBoolean();
       char ch = ois.readChar();
       System.out.println(msg);
       /*对象的数据还原*/
       Object str = ois.readObject();
       Object date = ois.readObject();
       Object employee = ois.readObject();

       /*将序列化内容反序列化--->还原对象*/
       if (str instanceof String){
           String strObject = (String) str;
           System.out.println(strObject);
      }

       if (date instanceof Date){
           Date date1 = (Date) date;
           System.out.println(date1);
      }

       if (emp instanceof Employee){
           Employee empObject = (Employee) employee;
           System.out.println(empObject.getName() + "--->" + empObject.getSalary());
           /*
           类里面代的get和set方法
           类型需要强转
            */
      }
  }
}

JavaBean

/**
* 自定义一个类实现Serializable接口实现可写入对象
* 写一个JavaBean类型
* javaBean类,后期主要用来封装数据用的
*/
class Employee implements java.io.Serializable{
   private String name;
   private double salary;
   private int age;

   /*构造方法*/
   public Employee() {
  }

   /*写Javabean方法*/
   public Employee(String name, double salary, int age) {
       this.name = name;
       this.salary = salary;
       this.age = age;
  }

   /*get和set方法*/
   public void setName(String name) {
       this.name = name;
  }

   public void setSalary(double salary) {
       this.salary = salary;
  }

   public void setAge(int age) {
       this.age = age;
  }

   public String getName() {
       return name;
  }

   public double getSalary() {
       return salary;
  }

   public int getAge() {
       return age;
  }
}
transient

假如某一个属性不需要序列化,使用transient来修饰

package iostudy.data;

import java.io.*;
import java.util.Date;

/**
* 数据流
* 1、先写出在读取--->先写出在读取--->写出到文件当中
* 2、读取的顺序和写出的顺序一致
* 本质:
* 将对象存储到硬盘当中,使其随时可以传输--->序列化到文件,存储到硬盘当中了
* @since JDK 1.8
* @date 2021/5/24
* @author Lucifer
*/
public class ObjectTestNo2 {
   public static void main(String[] args) throws IOException, ClassNotFoundException {

       //写出
       ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("abc.ser")));
       //操作数据类型 + 数据
       oos.writeUTF("唔系嫡系");
       oos.writeInt(21);
       oos.writeBoolean(false);
       oos.writeChar('c');
       //写入对象
       oos.writeObject("玛卡巴卡");
       oos.writeObject(new Date());
       Employee2 emp = new Employee2("码云", 5000, 50);
       oos.writeObject(emp);
       /*
       注意
       无论是String还是Date它们都已经再类中实现了接口Serializable
        */
       //刷新一下
       oos.flush();
       /*
       上面的操作是将那些数据类型的数据写入到字节数组缓冲流当中
        */
//       //存放数据的字节数组
//       byte[] datas = baos.toByteArray();
//
       //读取--->返序列化
       ObjectInputStream ois = new ObjectInputStream(
               //最外层装饰器
               new BufferedInputStream(
                       new FileInputStream("abc.ser")
              )
      );
       /*文件的后缀与流本身无关*/
       /*
       有里到外
       1、节点流
       2、节点数据类型转换流
       3、装饰流
        */
       //按照写入的数据类型读取
       String msg = ois.readUTF();
       int age = ois.readInt();
       boolean flag = ois.readBoolean();
       char ch = ois.readChar();
       System.out.println(msg);
       /*对象的数据还原*/
       Object str = ois.readObject();
       Object date = ois.readObject();
       Object employee = ois.readObject();

       /*将序列化内容反序列化--->还原对象--->序列化也称为持久化*/
       if (str instanceof String){
           String strObject = (String) str;
           System.out.println(strObject);
      }

       if (date instanceof Date){
           Date date1 = (Date) date;
           System.out.println(date1);
      }

       if (emp instanceof Employee2){
           Employee2 empObject = (Employee2) employee;
           System.out.println(empObject.getName() + "--->" + empObject.getSalary());
           /*
           类里面代的get和set方法
           类型需要强转
            */
      }
  }
}

 

 

posted @ 2021-05-26 10:04  俊king  阅读(300)  评论(0)    收藏  举报