java reader string_关于java:我应该关闭StringReader吗?

我使用StringReader将字符串转换为可以上传到SFTP服务器的字符串(它需要一个流)。 之后关闭那个StringReader有什么意义吗? 据我所知,它只是将字符串设置为null ...

我可以这么做,但是因为close方法被标记为抛出IOException而且我必须将它包装在try catch中并且代码最终看起来比它可能需要的更加可怕。

如果你知道你正在处理一个你将丢弃的StringReader,我认为没有理由关闭它。在你关闭它之后我无法想象你有什么理由持有它的引用,所以对于垃圾收集设置为null的字符串没有任何实际好处。如果您正在创建一个采用Reader的方法,那么关闭它可能是有意义的,因为您不知道底层类型。

是的,如果我不知道我正在处理什么样的Reader,我肯定会关闭它。

虽然严格来说没有必要,因为StringReader只保留一个字符串,作为一个良好的形式,它总是一个好主意,无论如何关闭所有读者。今天你的代码可能正在使用StringReader,但是如果你把它改成了另一个真正需要关闭的Reader,你的代码没有结束将是错误的,而你的w / close会很好。

你的意思是"会出错"不是吗?:-)

它不止于此。如果我可以引用JavaDoc:

/**

* Closes the stream and releases any system resources associated with

* it. Once the stream has been closed, further read(),

* ready(), mark(), or reset() invocations will throw an IOException.

* Closing a previously closed stream has no effect.

*/

是的,你应该关闭那个读者。不是为了资源,而是为了好风格和程序员可能会跟随你。您不知道此实例将传递到何处以及其他人将尝试使用它做什么。有一天,您可能还会选择更改界面并接受任何Reader实现,在这种情况下,您可能会处理需要调用close()来释放资源的Reader。

因此,一旦完成此实例,防止进一步(可能是错误的)使用它是一种很好的方式。而且由于它没有受到伤害,它只能防止将来出现可能的错误。

编辑:

既然你说,你的close()方法声明了一个异常它可能会抛出我会说你需要调用close(),因为StringReader.close()不会抛出异常。但是,Reader.close()可以。因此,您已经允许其他Reader实现,因此您必须关闭它,因为您无法知道最终将获得哪些Reader实现。如果我们讨论的是从不离开该范围的三行代码,请声明您的变量StringReader并且无论如何都要调用close(在这种情况下没有异常处理)。

给定StringReader从String读取什么系统重新存在,如果所有它都是String,它将被释放?

正如我所说,对于StringReader而言,它不是资源问题。 但是Reader的其他实现可能会有所不同。 根据您的界面和可能的未来变化,它可能会在某一天变得相关,即使它只是一个StringReader,它仍然是好的风格。

我知道doc说的是,但是当查看源代码时,它只将字符串设置为null(这当然会使其他方法崩溃)

也许我的编辑有帮助? 看起来你刚刚用错误的类型声明了你的变量。 StringReader.close()没有在我的Java6u20副本中声明异常。

如果变量的类型为StringReader而不是Reader,则不需要捕获异常,因为StringReader#close()不会抛出异常:只有Reader#close()。因此,您可以使用try-with-resources自动关闭阅读器,而无需使用样板来处理不会发生的异常。 Reader#close() throw IOException意味着子类型可以抛出这种类型的异常,而不是它们必须抛出的异常。这是您想要使用子类型而不是超类型声明变量的罕见情况之一;请参阅在java中使用接口或类型进行变量定义?更多。

因此,我建议以下,只需要一个嵌套级别,这是资源的标准:

try (StringReader reader = new StringReader(string)) {

// Do something with reader.

}

但是,关闭StringReader没有什么价值,因为它没有外部资源(只有Java管理的内存,而不是文件句柄或本机内存,所以),所以可以省略它,尽管我是推荐一个评论说明为什么这是安全的,因为否则不会关闭读者是令人惊讶的。正如您所注意到的,close()只是将字段空出来,每个JDK 8源:StringReader.java:198。如果你想避免嵌套和关闭,你可以这样写:

// Don't need to close StringReader, since no external resource.

StringReader reader = new StringReader(string);

// Do something with reader.

...或(使用更通用的变量类型):

// Don't need to close StringReader, since no external resource.

Reader reader = new StringReader(string);

// Do something with reader.

正常的资源尝试在这里工作,因为StringReader#close()覆盖Reader#close()并且仁慈地声明它不会抛出IOException。

请注意,这不是StringWriter的情况:StringWriter#close()确实声明它抛出IOException,尽管它是一个nop!这可能是为了向前兼容,因此它可能会在未来的实现中引发异常,尽管这不太可能。看我的回答

不会关闭字符串写入器导致泄漏吗?

在这种情况下(如果方法没有抛出异常,但接口声明它可以),那么你可能提到的写这个的紧密方法是:

Reader reader = new StringReader(string);

try {

// Do something with reader, which may or may not throw IOException.

} finally {

try {

reader.close();

} catch (IOException e) {

throw new AssertionError("StringReader#close() cannot throw IOException", e);

}

}

这个级别的样板是必要的,因为你不能只在整个try块上设置一个catch,否则你可能会意外地吞下代码体所抛出的IOException。即使目前没有,也可能会在未来添加一些,并且您希望编译器对此进行警告。另请注意,记录当前行为的AssertionError还会掩盖try语句主体抛出的异常,但这绝不会发生。如果这是替代方案,你最好省略close()并评论原因。

这个答案取决于你自己创造StringReader的事实;当然,如果你从其他地方收到Reader(比如工厂的返回类型),那么你需要关闭它并处理可能的异常,因为你不知道它可能拥有什么资源,它可能会抛出异常。

如果关闭流并释放与其关联的任何系统资源。关闭流后,进一步的read(),ready(),mark()或reset()调用将抛出IOException。关闭先前关闭的流无效。

具体说明:

关闭接口Closeable

具体说明:

在课堂上关闭

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值