PrintWriter和PrintStream永远不会抛出IOExceptions。

24

几天前我意识到PrintWriter(以及PrintStream)在写入,刷新或关闭时从不抛出IOException

相反,当发生错误时,它会设置一个内部标志(trouble=true)。
无法获取确切的异常,但只能通过checkError()来确定是否有异常。

我的问题是:为什么要这样做?这不是糟糕的API设计吗?


2
我只是在查这个。我也发现它非常奇怪。隐藏异常是一回事,但完全丢掉它呢?如果我真的想知道异常的内容怎么办?我期望有一个getError()方法,但这确实是一个非常奇怪的设计决定。 - aberrant80
6个回答

11

我认为由于System.outSystem.errPrintStream的实例,所以提供了一些更轻松的错误处理方式。正如其他帖子中提到的那样,这可能是为了使那些从C/C++ 1995年左右过渡的人更加顺畅。当添加Reader/Writer API时,创建了PrintWriter来与现有的PrintStream并行。

这种行为极其适用于日志记录。日志记录是一个大型应用程序的附属服务。通常,如果日志记录失败,则不希望整个应用程序都失败。因此,至少对于System.err来说,忽略异常是有意义的。


7

我想这是因为IOExceptions是被检查的,这会要求你在每个System.out.调用周围放置一个try catch块。

更新:或者在你的方法签名中加上throws。

那会很快变得很烦人。


一个已检查异常并不严格要求使用try-catch块。PrintStream在生产代码中很少使用,在核心库中的使用仅限于日志记录,其中失败可以安全地忽略。 - erickson
他们仍然可以抛出运行时异常,而不是IOException,而不是设置内部标志。 - Gonen I

1
Sun/Oracle应该添加两个类似写入的函数,一个会抛出IOException,另一个则不会抛出任何异常。

1

我不是很清楚这个故事,但我认为它的目的是让Java更容易使用,特别是对于那些设计师希望能够使用简单的stdio打印方法而无需知道异常处理的新手程序员。因此,在这方面,这是一个好的设计(尽管我有些同意你的看法)。


0

有可能这个设计是由一个来自C语言背景的人完成的,因为stdio错误处理方式类似。由于我习惯了这种范式,我不会说它不好,但我同意它是不一致的。

我也同意关于尝试让PrintWriter更易于使用的评论。Java中的IO类很令人困惑(至少对我认识的每个人都是如此),也许有人只是想让生活变得更轻松一些。


0

这不是设计错误。它是一种适合在写输出并希望忽略错误的情况下使用的正确设计。

作为典型用例,已经提到了System.outSystem.err,但原因不是为了方便或平稳的C/C++过渡而进行的放松处理。而是期望处理这样的情况:

  • 您在控制台中启动应用程序
  • 它将输出产生到标准输出/错误
  • 您关闭控制台,但希望应用程序继续在后台运行

在这种情况下,根据系统实现的不同,可能会发生System.outSystem.err在关闭控制台后失败,但您不希望这会导致应用程序崩溃。希望应用程序继续在后台运行,并且输出意味着被刮擦。这就是PrintWriter的作用。

如果您关心输出过程中的错误,请使用FileWriterOutputStreamWriter。如果您需要一些PrintWriter中可用但FileWriter中不可用的方法,请创建自己的TextWriter,继承FileWriterOutputStreamWriter

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