通过终止程序关闭流 - 常见做法?

Closing Stream by terminating program - Common practice?

我有一个实现 Runnable 的音频播放器。它开始发出声音,然后终止。这是一种常见的做法,还是我应该自己关闭它,就像目前没有使用的最后一种方法一样。在我看来,让它自动终止并强制关闭其余部分是个好主意。

public class AudioPlayer implements Runnable {

    AudioInputStream audioIn;
    Clip clip;

    public AudioPlayer (String res) {

        try {
            URL url = this.getClass().getResource(res);
            audioIn = AudioSystem.getAudioInputStream(url);
            clip = AudioSystem.getClip();
            clip.open(audioIn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        clip.start();
    }

    public void close() throws IOException {
        try {
            clip.close();
            audioIn.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

直接回答你的问题:不,这不是常见做法,而是不好的做法!

一般来说,获取资源而不显式释放它们是不好的做法。特别是对于流 - 背后可能有文件句柄,各种各样的东西。打开它们并扔掉它们可能会起作用;但如前所述:只是不好的做法。并注意:对于任何一种旨在 运行 更长时间的程序...它不仅 "good" 释放资源,它是绝对 必须 这样做。

特别是考虑到 Java 7 多年前就引入了 try-with-resources。

我建议在使用后立即释放 memory/resources,为此,存在 finally 块:

public AudioPlayer (String res) {
    try {
        URL url = this.getClass().getResource(res);
        audioIn = AudioSystem.getAudioInputStream(url);
        clip = AudioSystem.getClip();
        clip.open(audioIn);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        close();
    }
}

但是,如果您的音频流在完成后自动关闭,如果不是错误则无需强制关闭:

public AudioPlayer (String res) {
    try {
        URL url = this.getClass().getResource(res);
        audioIn = AudioSystem.getAudioInputStream(url);
        clip = AudioSystem.getClip();
        clip.open(audioIn);
    } catch (Exception e) {
        e.printStackTrace();
        close();
    }
}

请注意:要确保清理所有内容,您可能需要这样写:

public void close() throws IOException {
    try {
        clip.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        audioIn.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

要么在 run() 方法中打开流并在 finally 子句中关闭它们,要么实施 AutoCloseable 以便您的 class 可以用作资源。