try-with-resources 失败但尝试有效

Posted

技术标签:

【中文标题】try-with-resources 失败但尝试有效【英文标题】:try-with-resources fails but try works 【发布时间】:2019-06-15 19:45:35 【问题描述】:

我正在尝试设置一个侦听 RabbitMQ 服务器的服务,并且我使用 RabbitMQ Sample code from Github 设置了代码,其中包括以下 try-with-resources

try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) 
        // code here

当我使用相同的代码并使用java -cp myJar.jar MyService 构建和运行此服务时,它会立即开始和结束(并且echo $? 返回 0)

但是,如果我将块替换为以下内容,那么它可以使用相同的命令正常工作,并且我能够启动 RabbitMQ 实例的侦听器

try 
     Connection connection = factory.newConnection();
     Channel channel = connection.createChannel());

     // code here


即使我创建数据库连接也会发生同样的情况

try (Connection connection = dataSource.getConnection()) 
    //code here

失败但

try 
    Connection connection = dataSource.getConnection();
    //code here
  

工作正常,并且允许我使用连接来向数据库中输入条目。


为什么会这样?我正在使用OpenJDK 11.0.2,该服务是独立的,但如果有帮助,其余代码库是 JAX-RS 驱动的 Rest API。

【问题讨论】:

很难相信您的代码与您发布的内容一样有效,因为像 try … 这样的块甚至无法编译。 【参考方案1】:

try-with-resources 构造在块退出时关闭资源。您的基本尝试块代码不会关闭任何内容。这就是两者的区别。

当您使用 try-with-resources 时,您实际上需要对资源进行 DO 操作。

如果您正在编写代码,而您正在打开的资源需要“长期存在”,那么 try-with-resources 不是正确的构造(不过,通常这意味着您正在编写的类本身应该是自动关闭)。

【讨论】:

【参考方案2】:

在编程中使用 any 概念时,您必须了解自己在做什么!

try-with-resource 的重点是保证资源在 try 块结束时关闭。

但请注意:仅使用 try 块是不够的。像数据库连接这样的关键资源需要独特的、有意识的生命周期管理。换句话说:只要您需要,您就应该保留这些资源。并且您最好确保不要忘记在不再需要时关闭资源!

因此,您应该轻松地放弃 try-with-resource。而是确保在此类 try-with-resource 块的范围内调用需要此类资源的代码!

【讨论】:

以上是关于try-with-resources 失败但尝试有效的主要内容,如果未能解决你的问题,请参考以下文章

Try-with-resources 关闭生成的孩子的套接字

try-with-resources 中的两种关闭方法

在 Java 7 try-with-resources 的 Clover 检测后编译失败

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

java7 try-with-resources 很香

Java Try-With-Resources 辩论