当前位置: 首页 > 知识库问答 >
问题:

什么时候试用资源关闭资源?

秦滨海
2023-03-14

我正在为面向对象编程的秋季考试做准备,其中一种任务是提供代码输出,这通常包括一些异常处理问题。

现在我的问题是什么时候用资源尝试关闭它的资源,因为我的输出严格依赖于实现AutoCloseable的类的输出。

在提供的代码中,我不明白为什么“close 1”输出在“close 40”之前,或者为什么对象A(40)在这个块的末尾被关闭。是因为A(50)和A(40)是同一类型的吗?

我的主要问题是,AutoCloseable何时关闭给定的资源,比如在示例m1中,当i=1时:

1) 创建(1)1b)执行Try块2)关闭(1)3)ArrayIndexOutOfBoundsException已处理?

public class Main {
    public static void main(String[] args) {
          int[] arr = new int[] { 15, 10 };
          for(int i=1; i>=-1; i--){
              try(A a40 = new A(40)) {
                  m1(arr, i);
                  A a50 = new A(50);
              }
              catch(ArrayIndexOutOfBoundsException e) {
                System.out.println("array exc");
              }
              catch(Exception e) {
                System.out.println("main exc");
                break;
              }
              finally {
                System.out.println("main finally");
              }
          }
          System.out.println("main done");
        }

        private static void m1(int[] arr, int i) throws Exception {
          try(A a1 = new A(i)) {
            m2(arr[i] + arr[i+1], i);
          }
          catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("m1 exc");
          }
          System.out.println("m1 done");
        }

        private static int m2(int x, int y)  {
           int r = 0;
           try{
               A a2 = new A(x+y);
               r = x / y;
           }
           finally {
            System.out.println("m2 finally");
           }
           System.out.println("m2 done");
           return r;
        }
}

和实现AutoCloseable的类A:

public class A implements AutoCloseable {
      private int x;
      public A(int x){
        this.x = x;
           System.out.println("A " + x);
      }
      @Override
      public void close() throws Exception {
        System.out.println("close " + x);
      }
}

以下是提供的代码的输出:

A 40
A 1
close 1
m1 exc
m1 done
A 50
close 40
main finally
A 40
A 0
A 25
m2 finally
close 0
close 40
main exc
main finally
main done

共有1个答案

简景焕
2023-03-14

这方面的规范非常明确。

用资源尝试语句用局部变量(称为资源)参数化,这些变量在try块执行前初始化,并在try块执行后自动关闭,顺序与初始化它们的顺序相反。

你的例子有点复杂。尽量简化它。您感兴趣的场景有两种:在try块中抛出异常,在try块中不抛出异常。调试消息具有信息性,因此可以轻松跟踪流。

您可能需要查看反编译。类来查看实际生成的内容。

 类似资料:
  • 不管错误情况如何,使用资源尝试是否总是关闭资源?我的意思是考虑以下代码: 会一直关闭吗?我读过Oracle文档,其中说: 无论try语句是正常完成还是突然完成,它都将关闭 因此无论程序正常运行还是抛出异常,它都将起作用。但是,类似或崩溃的情况怎么办?我知道这些条件对块不起作用。那么,使用资源尝试失败的条件是否存在? 这只是我请求的好奇心,谁能说明这一点吗?

  • 我知道,如果资源已实现自动关闭,您通过尝试传递的资源将自动关闭。到现在为止,一直都还不错。但是,当我有几个我想要自动关闭的资源时,我该怎么办呢。带插座的示例; 所以我知道套接字将被正确关闭,因为它在try中作为参数传递,但是输入和输出应该如何正确关闭呢?

  • 问题内容: 我正在编写一个连接到网站并从中读取一行的应用程序。我这样做是这样的: 好吗?我的意思是,我在最后一行关闭了BufferedReader,但没有关闭InputStreamReader。我是否应该从connection.getInputStream创建一个独立的InputStreamReader,并从独立的InputStreamReader创建一个BufferedReader,而不是关闭所

  • 根据Oracle文档 try with resources语句是声明一个或多个资源的try语句。资源是一个对象,在程序完成后必须关闭它。try with resources语句确保在语句末尾关闭每个资源。任何实现java的对象。AutoCloseable,其中包括实现java的所有对象。伊奥。可关闭,可用作资源 如果资源未实现AutoCloseable,则无法在try块中声明,必须在主体部分中声明

  • 问题内容: 大多数情况下,我看到的finally块仅用于 我的问题是,如果f的范围以封闭块结尾,为什么我们需要在finally中将其关闭? 问题答案: 因为垃圾回收与资源清理 不是 一回事。 例如,如果您有一个超出范围的JDBC连接对象,则没有信号发送到数据库服务器以指示不再需要打开的游标和连接。没有这些消息,您最终将耗尽可用的游标和连接数。 与文件句柄和任何其他资源相同。自己清理后。

  • 问题内容: 我想知道如果不关闭ResultSet是否可以将其关闭?我有一个ResultSet已关闭异常,但是我确定我没有在任何地方关闭ResultSet。我的确切做法是,我使用ResultSet来执行SELECT查询,然后使用相同的ResultSet,因为此方法调用了ResultSet: 那么,另一个问题是:有没有一种方法可以确保打开ResultSet? 第三个问题:也许是问题所在,因为我从不关闭