116

Java 是否有在休眠中打开会话时可以使用的 using 语句?

在 C# 中,它类似于:

using (var session = new Session())
{


}

所以对象超出范围并自动关闭。

4

12 回答 12

138

Java 7 引入了自动资源块管理,将这一特性带到了 Java 平台。Java 的早期版本没有任何类似using.

例如,您可以使用java.lang.AutoCloseable以下方式实现的任何变量:

try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
    ...
}

Java 的java.io.Closeable接口,由流实现,自动扩展AutoCloseable,因此您已经可以在块中使用流,就像在 C#块try中使用它们一样。using这相当于 C# 的using.

5.0 版开始,Hibernate Sessions 实现AutoCloseable并且可以在 ARM 块中自动关闭。在以前版本的 Hibernate Session 中没有实现AutoCloseable。因此,您需要在 Hibernate >= 5.0 上才能使用此功能。

于 2010-01-06T21:17:31.873 回答
32

在 Java 7 之前,Java 中没有这样的功能(对于 Java 7 及更高版本,请参阅Asaph关于ARM的回答)。

您需要手动完成,这很痛苦

AwesomeClass hooray = null;
try {
  hooray = new AwesomeClass();
  // Great code
} finally {
  if (hooray!=null) {
    hooray.close();
  }
}

这只是既// Great code不能也hooray.close()不能抛出任何异常的代码。

如果您真的只想限制变量的范围,那么一个简单的代码块就可以完成这项工作:

{
  AwesomeClass hooray = new AwesomeClass();
  // Great code
}

但这可能不是你的意思。

于 2010-05-31T12:39:22.490 回答
20

从 Java 7 开始:http: //blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec

问题中代码的语法是:

try (Session session = new Session())
{
  // do stuff
}

请注意,Session需要实现AutoClosable或其(许多)子接口之一。

于 2011-08-24T08:17:41.093 回答
8

技术上:

DisposableObject d = null;
try {
    d = new DisposableObject(); 
}
finally {
    if (d != null) {
        d.Dispose();
    }
}
于 2010-01-06T21:18:13.923 回答
8

最接近的 java 等价物是

AwesomeClass hooray = new AwesomeClass();
try{
    // Great code
} finally {
    hooray.dispose(); // or .close(), etc.
}
于 2010-05-31T12:40:30.593 回答
3

到目前为止,没有。

但是,有一个针对 Java 7的ARM提案。

于 2010-01-06T21:20:51.163 回答
3

如果您对资源管理感兴趣,Project Lombok提供了@Cleanup注释。直接取自他们的网站:

您可以使用它@Cleanup来确保在代码执行路径退出当前范围之前自动清理给定资源。您可以通过使用注释来注释任何局部变量声明来做到这一点,@Cleanup 如下所示:

@Cleanup InputStream in = new FileInputStream("some/file");

结果,在您所在范围的末尾,in.close()被调用。此调用保证通过 try/finally 构造运行。查看下面的示例以了解其工作原理。

如果您要清理的对象类型没有close() 方法,但有其他无参数方法,您可以指定此方法的名称,如下所示:

@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);

默认情况下,清理方法假定为 close(). 不能通过 调用带参数的清理方法 @Cleanup

香草爪哇

import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }
}

与龙目岛

import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}
于 2010-05-31T13:13:34.007 回答
2

不,Java 没有using等效的语句。

于 2010-01-06T21:18:03.597 回答
2

在 java 8 中,您可以使用 try。请参考下页。http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

于 2014-08-13T13:56:47.933 回答
1

请参阅此Java 关键字列表

  1. 不幸的是,该using关键字不是列表的一部分。
  2. 并且目前在 Java 中也没有using任何其他关键字与 C# 关键字等价。

要模仿这种"using"行为,您将不得不使用一个try...catch...finally块,您将在其中处理finally.

于 2010-05-31T12:41:44.790 回答
1

来自项目 coin的ARM 块将在 Java 7 中。此功能旨在使用语法为 Java 带来与 .Net 类似的功能。

于 2010-05-31T12:42:52.537 回答
0

回答有关限制变量范围的问题,而不是谈论自动关闭/处置变量。

在 Java 中,您可以使用大括号定义封闭的匿名范围。这非常简单。

{
   AwesomeClass hooray = new AwesomeClass()
   // Great code
}

该变量hooray仅在此范围内可用,不在此范围之外。

如果您有只是临时的重复变量,这将很有用。

例如,每个都有索引。就像item变量在 for 循环中关闭(即,仅在其中可用)一样,index变量在匿名范围内关闭。

// first loop
{
    Integer index = -1;
    for (Object item : things) {index += 1;
        // ... item, index
    }
}

// second loop
{
    Integer index = -1;
    for (Object item : stuff) {index += 1;
        // ... item, index
    }
}

如果您没有 for 循环来提供变量范围,但您想使用通用变量名,我有时也会使用它。

{
    User user = new User();
    user.setId(0);
    user.setName("Andy Green");
    user.setEmail("andygreen@gmail.com");
    users.add(user);
}

{
    User user = new User();
    user.setId(1);
    user.setName("Rachel Blue");
    user.setEmail("rachelblue@gmail.com");
    users.add(user);
}
于 2013-09-26T13:34:46.793 回答