try-with-resource与序列化

public static void main(String[] args) throws FileNotFoundException {
   /**
    * 打印流与缓存读取流,打印流用于打印字符。S
    * ystem.out的类型是PrintStream,字符输出(打印流)。
    * 自己创建一个打印流。
    */


   //表示打印到c盘的c.txt文件。字符流。

   PrintStream ps = new PrintStream("c://c.txt");

   //可以调用打印流的方法

   ps.println("任意字符串");

   //表示打印到c盘的c.txt文件。字节流。

   PrintWriter pw = new PrintWriter("c://c.txt");

   //可以调用打印流的方法

   pw.println("任意字符串");

   //字符流与字节流最大的区别就是是否要刷新管道,字符流需要刷新管道。

   //不刷新管道就看不到。

   pw.flush();
}

try-with-resource

public static void main(String[] args) {
   /**
    * 关闭资源的方法一:
    *     在try块里声明资源,在finally块里关闭资源,
    *     防止在try块里出现异常导致资源无法关闭。
    *     但是这样会有一个问题,在finally块里要关闭资源
    *     还会要写try...catch语句。
    */
   FileReader fr = null;
   try {
       fr = new FileReader("c://book.txt");
       int c = fr.read();
       System.out.println((char)c);
  } catch (IOException e) {
       e.printStackTrace();
  } finally {
       try {
           fr.close();
      } catch (IOException e) {
           e.printStackTrace();
      }
  }
}
public static void main(String[] args) {
   /**
    * 关闭资源的方法二:
    *     在try块里的小括号中声明资源(要完整的新建对象语句才行),资源会自动关闭。
    * 能在try块的小括号中声明的资源其类或者继承的父类中必须实现Closeable接口或者AutoCloseable接口。
    */
   try (FileReader fr = new FileReader("c://book.txt")){
       int c = fr.read();
       System.out.println((char)c);
  } catch (IOException e) {
       e.printStackTrace();
  }
}
public static void main(String[] args) {
   /**
    * 自定义实现Closeable接口的类。
    */
   try (CloseDemo c = new CloseDemo()) {
       
  } catch (IOException e) {
       e.printStackTrace();
  }
}

static class CloseDemo implements Closeable {

   @Override
   public void close() throws IOException {
       System.out.println("close方法被调用了");
  }
}

序列化与反序列化

想要序列化的类要实现Serializable接口,类中不想实现序列化的属性添加transient修饰词,static修饰的属性也不会参与序列化。

public class Demo2 implements Serializable{
   private transient String name;
   private int age;
   private  List<String> family = new ArrayList<>();

   public Demo2(String name, int age, List<String> family) {
       this.name = name;
       this.age = age;
       this.family = family;
  }

   @Override
   public String toString() {
       return "Demo2{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", family=" + family +
               '}';
  }

   public static void main(String[] args) throws IOException, ClassNotFoundException {
       List<String> family = new ArrayList<>();
       family.add("爸爸");
       family.add("妈妈");
       Demo2 demo = new Demo2("张三",30, family);
       System.out.println(demo);
       OutputStream os = new FileOutputStream("d://1.txt");
       ObjectOutputStream oos = new ObjectOutputStream(os);
       oos.writeObject(demo);
       os.close();
       oos.close();
       InputStream is = new FileInputStream("d://1.txt");
       ObjectInputStream ois = new ObjectInputStream(is);
       Object o = ois.readObject();
       is.close();
       ois.close();
       System.out.println(o);
  }
}

或者在想要序列化的类中写私有方法writeObject与readObject,两个方法中序列化与反序列化的属性都要对应,当序列化或反序列化时,虚拟机会找到这两个方法运行方法内相应代码,在方法内写上要序列化的属性,该属性就会被序列化,没有写的属性就不会序列化。如果没有这两个方法,就会调用ObjectStreamClass中默认的这两个方法序列化属性。

public class Demo2 implements Serializable{
   private String name;
   private int age;
   private  List<String> family = new ArrayList<>();

   public Demo2(String name, int age, List<String> family) {
       this.name = name;
       this.age = age;
       this.family = family;
  }

   @Override
   public String toString() {
       return "Demo2{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", family=" + family +
               '}';
  }

   private void writeObject(ObjectOutputStream oos) throws IOException {
       System.out.println("writeObject方法被调用了。");
       oos.writeObject(name);
       oos.writeObject(family);
  }

   private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
       System.out.println("readObject方法被调用了。");
       name = (String) ois.readObject();
       family = (List<String>) ois.readObject();
  }

   private static void demo2Serializable(Demo2 demo2, String filePath) throws IOException {
       OutputStream os = new FileOutputStream(filePath);
       ObjectOutputStream oos = new ObjectOutputStream(os);
       oos.writeObject(demo2);
       os.close();
       oos.close();
  }

   private static Object demo2DeSerializable(String filePath) throws IOException, ClassNotFoundException {
       InputStream is = new FileInputStream(filePath);
       ObjectInputStream ois = new ObjectInputStream(is);
       Object o = ois.readObject();
       is.close();
       ois.close();
       return o;
  }

   public static void main(String[] args) {
       List<String> family = new ArrayList<>();
       family.add("爸爸");
       family.add("妈妈");
       Demo2 demo = new Demo2("张三",30, family);
       System.out.println("原始数据:" + demo);
       String filePath = "d://1.txt";
       try {
           demo2Serializable(demo, filePath);
      } catch (IOException e) {
           e.printStackTrace();
      }
       try {
           Object o = demo2DeSerializable(filePath);
           System.out.println("反序列化后数据:" + o);
      } catch (IOException e) {
           e.printStackTrace();
      } catch (ClassNotFoundException e) {
           e.printStackTrace();
      }
  }
}

还可以通过实现Externalizable接口(继承自Serializable接口)实现序列化与反序列化,要重写该接口中的两个方法,相当于writeObject与readObject方法。一般使用在想要自定义想要序列化属性的时候。

上一篇:Tcplistener服务端与tcpclient客户端使用


下一篇:CSS字体系列(CSS、HTML)