使用 try-with-resources 重写此代码

Posted

技术标签:

【中文标题】使用 try-with-resources 重写此代码【英文标题】:Rewrite this code using try-with-resources 【发布时间】:2020-08-19 15:10:14 【问题描述】:

这段代码用于通过java序列化复制一个实例。它使用传统的 try-catch-finally 编写方法。可以改成try-with-resources形式吗?(代码中的DeepConcretePrototype是一个普通的java对象)

    /**
     * Clone an instance through java serialization
     * @return
     */
    public DeepConcretePrototype deepCloneBySerializable() 
        DeepConcretePrototype clone = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;
        try 
            //Output an instance to memory
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);
            objectOutputStream.flush();
            //Read instance from memory
            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            clone = (DeepConcretePrototype)objectInputStream.readObject();
         catch (IOException e) 
            e.printStackTrace();
         catch (ClassNotFoundException e) 
            e.printStackTrace();
         finally 
            if (byteArrayOutputStream != null) 
                try 
                    byteArrayOutputStream.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
            if (objectOutputStream != null) 
                try 
                    objectOutputStream.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
            if (byteArrayInputStream != null) 
                try 
                    byteArrayInputStream.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
            if (objectInputStream != null) 
                try 
                    objectInputStream.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
        return clone;
    

【问题讨论】:

【参考方案1】:

是的,您可以使用 try-with-resources,但这有点棘手,因为 read 的成功取决于 write 的成功。编写它的一种方法是使用嵌套的try

public DeepConcretePrototype deepCloneBySerializable() 
    DeepConcretePrototype clone = null;

    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) 
        //Output an instance to memory
        objectOutputStream.writeObject(this);
        objectOutputStream.flush();

        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
             ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) 
            //Read instance from memory
            clone = (DeepConcretePrototype) objectInputStream.readObject();
        

     catch (IOException e) 
        e.printStackTrace();
     catch (ClassNotFoundException e) 
        e.printStackTrace();
    

    return clone;

【讨论】:

实际上,这里完全不需要关闭,因为这些流不封装真实资源。 flush() 是唯一需要的操作,无论如何都是在这里手动完成的。此外,您可以使用catch(IOException|ClassNotFoundException e) … ,尽管在错误时返回null 是一个有问题的行为…… 没错,我认为 OP 有兴趣了解如何使用 try-with-resources。

以上是关于使用 try-with-resources 重写此代码的主要内容,如果未能解决你的问题,请参考以下文章

此语言级别不支持 try-with-resources - Android

Java8 Try-with-resource/JDBC/Play 框架:这是正确的吗?

我应该为每一行日志使用 try-with-resources 语句吗?

使用 try-with-resources 读取和写入同一个文件

java7 try-with-resources 很香

Java 使用 Clip 和 Try - with - resources 块,结果没有声音