Java中是否有类似C#的using语句,在Hibernate打开会话时使用?
在C#中,它是这样的:
using (var session = new Session())
{
}
所以对象超出作用域后会自动关闭。
Java中是否有类似C#的using语句,在Hibernate打开会话时使用?
在C#中,它是这样的:
using (var session = new Session())
{
}
所以对象超出作用域后会自动关闭。
Java 7引入了自动资源管理块(Automatic Resource Block Management),将此功能引入到Java平台中。在此之前的Java版本中没有任何类似于using
的东西。
例如,你可以以以下方式使用实现了java.lang.AutoCloseable
接口的任何变量:
try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
...
}
Java的java.io.Closeable
接口由流实现,自动扩展了AutoCloseable
,因此您可以在try
块中像在C#的using
块中使用流一样使用它们。这相当于C#的using
。
从版本5.0开始,Hibernate Sessions实现了AutoCloseable
并可以在ARM块中自动关闭。在Hibernate的早期版本中Session没有实现AutoCloseable
。因此,您需要使用Hibernate >= 5.0才能使用此功能。
using
所做的事情)。 - Joachim SauerAutoCloseable
在 Java 7 之前不存在,对吧? - Neiljava.io.Closeable
接口,你会在 Java 7 代码中得到 try 语句。 - usr-local-ΕΨΗΕΛΩΝ在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
}
但这可能不是你的意思。
从Java 7开始,它这样做:http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec
问题中代码的语法应该是:
try (Session session = new Session())
{
// do stuff
}
请注意,Session
需要实现AutoClosable
接口或其(众多)子接口之一。
从技术角度来说:
DisposableObject d = null;
try {
d = new DisposableObject();
}
finally {
if (d != null) {
d.Dispose();
}
}
最接近的Java等价物是
AwesomeClass hooray = new AwesomeClass();
try{
// Great code
} finally {
hooray.dispose(); // or .close(), etc.
}
如果您对资源管理感兴趣,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);
}
}
}
using
关键字不幸地不在列表中。using
关键字。为了模仿这种"using"
行为,您将需要使用try...catch...finally
块,在其中您将在finally
中处理资源。
using
不是关键字并不代表什么。正如@BalusC所提到的,同样的功能可以(而且将会)使用另一个关键字实现。” - Joachim Sauerusing
不在Java关键字列表中意味着Java语言中没有这个功能。这是不正确的。 - Joachim Sauerusing
关键字或等价物。感谢@Joachim Sauer!=) - Will Marcouiller
using
的作用。范围不等于生命周期(严格来说,using
也不涉及生命周期,因为Dispose
不会销毁对象的内存)。 - Joren