我想知道以下代码是否正确使用try-with-resources.
try (ResultSet rs = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build().executeQuery()) {
while (rs.next()) {
beans.add(createBean(rs));
}
}
Run Code Online (Sandbox Code Playgroud)
争论并不重要,唯一重要的是:
new QueryBuilder().build();返回一个PreparedStatement.我完全理解rs将会被关闭,但也会PreparedStatement被关闭,如果是这样,原因是什么?因为ResultSet关闭还是因为尝试资源?
为什么Eclipse给出了一个奇怪的"资源泄漏:zin永远不会关闭"警告以下代码,即使我使用try-with-resources:
Path file = Paths.get("file.zip");
// Resource leak warning!
try (ZipInputStream zin = new ZipInputStream(Files.newInputStream(file))) {
for (int i = 0; i < 5; i++)
if (Math.random() < 0.5)
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
如果我在代码上修改"任何东西",警告就会消失.下面我列出了3个修改过的版本都没问题(没有警告).
Mod#1:如果我for从try块中删除循环,则警告消失:
// This is OK (no warning)
try (ZipInputStream zin = new ZipInputStream(Files.newInputStream(file))) {
if (Math.random() < 0.5)
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
Mod#2:如果我保留for …
这个新的Java 7 try-with-resources构造非常好.或者至少,这是很好的,直到一个例外走过来,毁了我的一天.
我终于把它归结为一个可重复的测试,它只使用JUnit + jMock.
@Test
public void testAddSuppressedIssue() throws Exception {
Mockery mockery = new Mockery();
final Dependency dependency = mockery.mock(Dependency.class);
mockery.checking(new Expectations() {{
allowing(dependency).expectedCall();
allowing(dependency).close();
}});
try (DependencyUser user = new DependencyUser(dependency)) {
user.doStuff();
}
}
// A class we're testing.
private static class DependencyUser implements Closeable {
private final Dependency dependency;
private DependencyUser(Dependency dependency) {
this.dependency = dependency;
}
public void doStuff() {
dependency.unexpectedCall(); // bug
}
@Override
public void close() throws IOException { …Run Code Online (Sandbox Code Playgroud) 我正在寻找使用Java 1.7的适当功能(try-with-resources)实现客户端/服务器套接字通信的最佳模式.必须确保所有线程和资源都已完全关闭和释放.应考虑有效的Java/Clean代码项以及简单的可调试性(每行只有一个语句).
任何反馈或讨论将不胜感激.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.junit.Test;
public final class ThreadedServerTest1 {
private static final class ThreadedServer implements Runnable {
private final Socket socket;
ThreadedServer(final Socket socket) {
this.socket = socket;
}
public static void main(final String arguments[]) {
final int port = arguments.length > 0 ? Integer.parseInt(arguments[0]) : 9999;
try (final ServerSocket …Run Code Online (Sandbox Code Playgroud) 使用Java 7u5和try-with-resources构造,以下代码似乎泄漏了jdbc连接:
try (Connection connection = ..; PreparedStatement stmt = ..) {
stmt.setString(..);
return stmt.executeUpdate() > 0;
}
Run Code Online (Sandbox Code Playgroud)
下一段代码按预期和预期工作:
int ret = 0;
try (Connection connection = ..; PreparedStatement stmt = ..) {
stmt.setString(..);
ret = stmt.executeUpdate();
}
return ret > 0;
Run Code Online (Sandbox Code Playgroud)
似乎在第一种情况下,该Connection.close()方法未被调用.
我正在使用最新的mysql连接器.这是出乎意料的行为,对吗?
以下测试不会打印CLOSED:
public class Test implements AutoCloseable {
public static void main(String[] args) throws Exception {
System.out.println(doTest());
}
private static boolean doTest() throws Exception {
try (Test test …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关JDK7中的try-with-resource的内容,当我考虑将我的应用程序升级为使用JDK7运行时,我遇到了这个问题.
当使用BufferedReader时,例如写入抛出IOException和close抛出IOException ..在catch块中我关注写入引发的IOException ..但我不会太在意关闭抛出的那个..
数据库连接和任何其他资源的问题相同..
作为一个例子,我创建了一个自动关闭资源:
public class AutoCloseableExample implements AutoCloseable {
public AutoCloseableExample() throws IOException{
throw new IOException();
}
@Override
public void close() throws IOException {
throw new IOException("An Exception During Close");
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用它时:
public class AutoCloseTest {
public static void main(String[] args) throws Exception {
try (AutoCloseableExample example = new AutoCloseableExample()) {
System.out.println(example);
throw new IOException("An Exception During Read");
} catch (Exception x) {
System.out.println(x.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何在不必为BufferedReader等类创建包装器的情况下区分这些异常?
大多数情况下,我将资源关闭在finally块中的try/catch中,而不关心处理它.
我最近和我的教授讨论了如何处理基本的jdbc连接方案.假设我们想要执行两个查询,这就是他的建议
public void doQueries() throws MyException{
Connection con = null;
try {
con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
PreparedStatement s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
rs.close();
s2.close();
s1.close();
} catch (SQLException e) {
throw new MyException(e);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e2) {
// Can't really do anything
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种方法,我有两个问题:
1.A),我认为,如果有异常,我们做"其他的事情",或者在该行抛出rs.close()还是 …
一般来说,我总是看到try-with-resources用于分配一个新的对象实例,close()当其超出范围时,该方法的方法被调用.
据我所知,创建一个新对象不是必需的,try-with-resources语法只需要一个局部变量来调用close(),当它超出范围时.因此,您可以使用它来控制"配对操作",例如从池中分配内容并确保返回它.
例如,下面的MyHandle显示了当您不再需要它时如何释放池化实例:
// init
class MyHandle implements AutoCloseable {
boolean inUse = false;
public MyHandle allocate() {
inUse = true;
return this;
}
public void close() {
inUse = false;
}
}
MyHandle[] pool = new MyHandle[POOL_SIZE];
for (int i = 0; i < pool.length; i++) {
pool[i] = new MyHandle(i);
}
// allocate
MyHandle allocateFromPool() {
for (int i = 0; i < pool.length; i++) {
if (!pool[i].inUse)
return pool[i].allocate();
}
throw new …Run Code Online (Sandbox Code Playgroud) 我是新手Java8,我想知道,对于AutoCloseable资源,我是否必须try为每个添加一个resource,或者它将使用上面的代码
try (Connection conn = getConnection();) {
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(sql);
while (rset.next()) {
TelefonicaDataVO vo = new TelefonicaDataVO();
vo.setTelefonicaDataId(rset.getString("Telefonica_PSD_ID"));
vo.setReceptionDate(nvl(rset.getTimestamp("CREATION_DATE")));
vo.setMessage(nvl(rset.getString("MESSAGE")));
ret.add(vo);
}
}
Run Code Online (Sandbox Code Playgroud) 考虑以下try-with-resources块:
try (Foo foo = getAFoo()) {
}
Run Code Online (Sandbox Code Playgroud)
对于某些Foo实现的类java.lang.AutoCloseable.
如果getAFoo()要返回null,那么是否会在结束括号上抛出空指针异常(由于运行时试图调用close)?