C/C++教程

try-with-resource与序列化

本文主要是介绍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方法。一般使用在想要自定义想要序列化属性的时候。

这篇关于try-with-resource与序列化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!