我有一个实现AutoCloseable的类,旨在与Java 7的新try-with-resources构造一起使用.但是,我无法找到一种方法来保证我的类的用户使用try-with-resources.如果没有发生这种情况,那么我的班级将无法自行关闭,并且会发生不好的事情.有没有办法 - 语言构造或其他 - 来强制执行此操作?甚至能够检测我是否在try-with-resources块中,以便我可以抛出异常(如果不是)会很好(尽管编译时构造会更好).
谢谢!
我有这个方法,我正在尝试使用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.为什么我会收到此错误以及如何解决?
谢谢
假设我使用的是一个记录不完整的第三方库,其中没有源代码可用.其中一个库的方法接受InputStream加载各种数据.
由于缺少文档,不清楚该方法是否在完成后关闭流,因此一种可能的解决方案可能是将调用包装在try-with-resource中,只是为了安全起见.
不幸的是,Java规范(据我所知)没有提到如果在try-with-resource中手动关闭资源会发生什么.有谁碰巧知道吗?
我有一个基类Base和一个Child扩展它的子类.Base实施java.lang.AutoCloseable.
让我们假设构造函数Child抛出一个Foo.
现在考虑
try (Base c = new Child()){
/*Some code*/
} catch (final Foo e){
/*Some more code*/
}
Run Code Online (Sandbox Code Playgroud)
Base#close如果抛出异常,是否调用该方法?它不在我的机器上,但这是JLS标准化的东西吗?
在以下代码块中:
try ( /* resources declaration */ ) {
// some dangerous code
} catch (Exception e) {
// error handling and reporting
}
Run Code Online (Sandbox Code Playgroud)
如果会发生什么,都在里面的代码try块和自动close()声明抛出异常?哪一个会陷入困境catch?他们都?只有其中一个?如果是这样,哪一个?
如果try成功但close不是?是否会输入捕获块?
在许多地方,也有建议称Realm.getDefaultInstance()中onCreate的方法Activity,并呼吁close在领域实例onDestroy(或演示者的相应方法).
但是,对我来说,使用Java的try-with-resources构造会更简洁:
try (final Realm realm = Realm.getDefaultInstance()) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
清洁为什么?IMO可以更轻松地管理该范围的realm实例.在生命周期的一个时刻获取实例并在另一个实例中关闭实例,让我想起过去使用C++的过去,当我们不得不担心delete在正确的时刻调用时.
问题是:以这种方式使用Realm是一种不好的做法吗?为什么没有教程提到它?
我正在查看 Java 中的 try-with-resources 示例,我了解以下内容:
try (Connection conn = DriverManager.getConnection(url, user, pwd);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);) {
...
}
Run Code Online (Sandbox Code Playgroud)
所以,关闭的顺序是:
rs.close();
stmt.close();
conn.close();
Run Code Online (Sandbox Code Playgroud)
这是完美的,因为一个连接有一个语句,而一个语句有一个结果集。
但是,在以下示例中,关闭的顺序我认为与预期相反:
示例 1:
try (FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr)) {
...
}
Run Code Online (Sandbox Code Playgroud)
关闭顺序为:
br.close();
fr.close();
Run Code Online (Sandbox Code Playgroud)
示例 2:
try (FileOutputStream fos = new FileOutputStream("testSer.ser");
ObjectOutputStream oos = new ObjectOutputStream(fs);) {
...
}
Run Code Online (Sandbox Code Playgroud)
关闭顺序为:
oos.close();
fos.close();
Run Code Online (Sandbox Code Playgroud)
这些例子正确吗?我认为这些例子中的结束应该有所不同,因为:
我在Java servlet类中有一个try-catch语句.Netbeans显示错误:
-source 1.6不支持try-with-resources(使用-source 7或更高版本来启用try-with-resources)
我怎样才能摆脱这个错误?
我对stackoverflow的第一个问题,我退出了;)
使用流链时,通常最好只关闭链中的最后一个流,因为close()操作应该在链的所有流中传播。
将try-with-source语句和流链接结合在一起时,什么被认为是好的做法?
a)在try语句中创建所有流:
try (InputStream processIn = p.getInputStream();
InputStreamReader inReader = new InputStreamReader(processIn);
BufferedReader input = new BufferedReader(inReader)) {
.
.
}
Run Code Online (Sandbox Code Playgroud)
或b)只是链中的最后一个成员:
InputStream processIn = p.getInputStream();
InputStreamReader inReader = new InputStreamReader(processIn);
try (BufferedReader input = new BufferedReader(inReader)) {
.
.
}
Run Code Online (Sandbox Code Playgroud)
我猜这两个版本最终都可以使用,但是我假设a)会生成重复的close()调用,不是吗?
我对Java的“尝试资源”功能有疑问。大多数示例似乎都遵循在try语句中声明和实例化资源的模型,如下所示:
try (BufferedReader in =
new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
...
}
Run Code Online (Sandbox Code Playgroud)
我需要将可关闭资源传递给方法,而我想知道是否有可能或建议将作为方法参数传递的可关闭资源的所有权传递给try块。例如:
void handleConnection(Socket clientSocket) {
try (Socket socket = clientSocket;
BufferedReader in =
new BufferedReader(new InputStreamReader(socket.getInputStream())); ) {
...
}
Run Code Online (Sandbox Code Playgroud)
这样可以正确清理clientSocket实例吗?我希望避免在代码中显式关闭clientSocket实例。