背景:我使用Java类InitialDirContext访问LDAP目录。 不幸的是,它没有实现interface AutoCloseable,因此不能在try-with-resources块中使用。
这是我写的原始代码:(受此答案启发)
final Properties props = new Properties();
// Populate 'props' here.
final InitialDirContext context = new InitialDirContext(props);
Exception e0 = null;
try {
// use 'context' here
}
catch (Exception e) {
// Only save a reference to the exception.
e0 = e;
// Why re-throw?
// If finally block does not throw, this exception must be thrown.
throw e;
}
finally {
try {
context.close();
}
catch (Exception …Run Code Online (Sandbox Code Playgroud) 在实现AutoCloseable使用Java 7 try-with-resources语句时,我想知道try块中是否存在异常.例如:
class C implements AutoCloseable {
@Override
public void close() {
if (exceptionOccurred)
something();
else
somethingElse();
}
}
Run Code Online (Sandbox Code Playgroud)
为了说明这一点:
try (C c = new C()) {
// This should cause a call to "something()"
if (something)
throw new RuntimeException();
// This should cause a call to "somethingElse()"
else
;
}
Run Code Online (Sandbox Code Playgroud)
现在,从了解try-with-resources语句如何转换为字节码,我想这是不可能的.但有没有(可靠!)技巧通过检测/反射/一些未记录的编译器功能,允许我RuntimeException从内部访问上述AutoCloseable.close()?
注意:我是一名API设计师,我无法控制API使用者的资源尝试代码.因此必须在AutoCloseable现场完成实施
我在读这个环节的try-with-resources,它说:
Closeable接口的close方法抛出类型的异常,IOException而AutoCloseable接口的close方法抛出类型的异常Exception.
但为什么?AutoCloseable可能还抛出的close方法IOException是有任何支持AutoCloseable必须抛出类型异常的close方法的例子Exception
根据http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#close()的文档,
关闭Statement对象时,其当前ResultSet对象(如果存在)也将关闭.
但是,虽然Connection之后关闭了,但是必须单独关闭必须JDBC结果集和语句?,明确关闭Connection Statement和似乎是一个好习惯ResultSet.
如果我们仍然需要关闭ResultSet,我们可能需要有一个嵌套的try-with-resources语句,因为我们可能会设置这样的参数Statement:
try (Connection conn = connectionProvider.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql) {//resources of conn and pst
setPrepareStatementParameter(pstmt, kvs);//need to set parameters, so I have to put ResultSet into another try-with-resources statement
try (ResultSet res = pstmt.executeQuery()) {
..............
}
}
Run Code Online (Sandbox Code Playgroud)
是否将ResultSet放入单独的try-with-resources语句中,因为doc声明Statementclose将关闭ResultSet
我正在使用IntelliJ IDEA Ultimate 2016.2.1,将Project SDK设置为我的1.8版本,将Project Language Level设置为8,将模块SDK设置为我的1.8版本,将JDK主路径设置为/Library/Java/JavaVirtualMachines/jdk1.8.0_91. JDK /内容/首页.
我重新启动了IDE.
尽管如此,我对这种语言级别不支持的资源尝试提出了丑陋的警告.我没有在IntelliJ中使用低于语言级别8,所以这不能归因于没有刷新的东西.我正在使用gradle构建配置 - 清理构建并尝试运行 - 说我正在运行1.5但我无法弄清楚提到1.5的位置.在build.gradle我正在使用:
apply plugin: 'java'
apply plugin: 'application'
sourceCompatibility = 1.8
Run Code Online (Sandbox Code Playgroud)
我应该提交IntelliJ错误还是我还缺少某些东西?
编辑:
在IntelliJ系统之外的termianl中运行gradle运行良好.所以问题是IntelliJ相关.
Autocloseable应始终使用try-with-resources.至少Intellij检查表明了这一点.所以,如果我有一个生成Foo该实现的代码,Autocloseable我应该这样做:
try (final Foo foo = getFoo()) {
foo.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
但是如果我有功能返回Foo[]怎么办?或接受Foo[](或Collection<Foo>)作为其参数的函数?
我怎么用它try-with-resources?查看以下功能:
Foo[] getFoos();
doAll(Foo... foo);
Run Code Online (Sandbox Code Playgroud)
我想做点什么 doAll(getFoos())
我怎样才能做到这一点?
AutoCloseable我正在一个块中创建可变数量的对象try-with-resources。在任何退出点,我都希望关闭所有分配的资源。
我可以想象自己写一些东西来做到这一点,但是是否有一个类似于Python 的 contextlib.ExitStack 的现有实用程序可以关闭分配的资源?我希望它看起来像这样:
try (ExitStack exitStack = new ExitStack()) {
List<Widget> widgets = new ArrayList<>();
for (...) {
widgets.add(exitStack.add(new Widget()));
}
// use widgets
}
Run Code Online (Sandbox Code Playgroud)
(注意:这不是这个问题,因为我不知道我会提前拥有多少资源。
嘿,亲密的选民,我不是在要求一个库,我是在问你如何完成安全关闭动态数量的任务AutoCloseable,如果有一个语言功能,那就太好了,如果有一个标准库函数,也很棒,如果我必须自己写,那很好。如果您想推荐一个常用的包含此内容的第三方库,那么当然可以。
考虑以下情况:
try (ResultSet resultSet = DriverManager.getConnection("jdbc:...", "user", "pass")
.createStatement().executeQuery(sql)) {
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
这是在资源内部创建了三个资源的情况try: a Connection、 aStatement和 a ResultSet。
try 块结束后这三个资源会发生什么变化?他们会全部关闭,即使他们没有任何提及它们,还是只会resultSet关闭?
AutoCloseable在尝试使用资源块时,在没有任何引用的情况下声明资源是否安全?
我有这个方法,我正在尝试使用Java SE 7的资源.
private void generateSecretWord(String filename){
try (FileReader files = new FileReader(filename)){
Scanner input = new Scanner(files);
String line = input.nextLine();
String[] words = line.split(",");
Collections.shuffle(Arrays.asList(words));
if (words[0].length()>1){
secretWord = words[0];
return;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally {
if (files!=null) files.close();
}
}
Run Code Online (Sandbox Code Playgroud)
我在finally块中得到编译错误,files cannot be resolved to a variable
我在文件中引用了文件try with block.为什么我会收到此错误以及如何解决?
谢谢
假设我在Java中有以下try-with-resources语句:
try (MyResource myResource1 = new MyResource(); MyResource myResource2 = new MyResource()) {
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
如果MyResource myResource2 = new MyResource()抛出异常,是否可以保证myResource1.close()将被调用?