如何在Java中使用PrintStream时找出发生的异常

9
我刚刚了解到,在Java中,类PrintStreamPrintWriter不会抛出已检查的异常。相反,它们使用一种错误标志,我可以通过调用方法boolean checkError()API链接)来读取该标志。

现在,我在想如何找出异常发生的原因。有时仅有异常信息可能是不够的,对吗?
1个回答

8

根据源代码,看起来他们丢弃了异常。所有的catch块都是这样的:

try {
    ...
}
catch (IOException x) {
    trouble = true; // (x is ignored)
}

因此,最直接的解决方案可能是尽可能不使用PrintStream

一种解决方法可能是扩展PrintStream并将输出包装在另一个OutputStream中,在PrintStream捕获(并丢弃)异常之前捕获异常。代码如下:

package mcve.util;

import java.io.*;

public class PrintStreamEx extends PrintStream {
    public PrintStreamEx(OutputStream out) {
        super(new HelperOutputStream(out));
    }

    /**
     * @return the last IOException thrown by the output,
     *         or null if there isn't one
     */
    public IOException getLastException() {
        return ((HelperOutputStream) out).lastException;
    }

    @Override
    protected void clearError() {
        super.clearError();
        ((HelperOutputStream) out).setLastException(null);
    }

    private static class HelperOutputStream extends FilterOutputStream {
        private IOException lastException;

        private HelperOutputStream(OutputStream out) {
            super(out);
        }

        private IOException setLastException(IOException e) {
            return (lastException = e);
        }

        @Override
        public void write(int b) throws IOException {
            try {
                super.write(b);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void write(byte[] b) throws IOException {
            try {
                super.write(b);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            try {
                super.write(b, off, len);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void flush() throws IOException {
            try {
                super.flush();
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void close() throws IOException {
            try {
                super.close();
            } catch (IOException e) {
                throw setLastException(e);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接