5

我正在使用方便的 try-with-resources 语句来关闭连接。这在大多数情况下效果很好,但只有在一种非常简单的方法中它不能正常工作。即,这里:

public boolean testConnection(SapConnection connection) {
  SapConnect connect = createConnection(connection);
  try ( SapApi sapApi = connect.connect() ) {
    return ( sapApi != null );
  } catch (JCoException e) {
    throw new UncheckedConnectionException("...", e);
  }
}

sapApi 对象非空,该方法返回 true,但从不调用 sapApi 的 close() 方法。我现在求助于使用 finally 块,它工作正常。但这很令人费解。Java 字节码还包含对关闭的调用。有没有人见过这种行为?

编辑以澄清情况:

这是 SapApi,它当然实现了 AutoCloseable。

class SapApi implements AutoCloseable {

  @Override
  public void close() throws JCoException {
    connection.close(); // this line is not hit when leaving testConnection(..)
  }
..
}

以下是与 testConnection(..) 相同的类中的另一个方法。这里 SapApi.close() 在返回之前被调用。

@Override
public List<Characteristic> selectCharacteristics(SapConnect aConnection,   InfoProvider aInfoProvider) {
  try (SapApi sapi = aConnection.connect()) {
    return sapi.getCharacteristics(aInfoProvider);
  } catch ( Exception e ) {
    throw new UncheckedConnectionException(e.getMessage(), e);
  }
}

编辑2:这是 SapConnect.connect():

SapApi connect() {
  try {
    ... // some setup of the connection
    return new SapApi(this); // single return statement
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

SapApi 没有子类。上面的 close 方法只有一种实现。特别是,没有空的 close()。

4

3 回答 3

2

为了调用 close(),SapApi 必须实现 AutoCloseable 接口,但是由于我们正在谈论连接,所以 SapApi 将实现抛出 IOException 的 Closable 接口更为合适。

阅读: http ://tutorials.jenkov.com/java-exception-handling/try-with-resources.html

于 2015-03-26T10:30:36.210 回答
1

我不知道你是什么意思

这在大多数情况下都很好用

1 通常SapApi在 try-with-resources 中使用时关闭

或者

2 它通常适用于除SapApi

我根据数字 2 的假设来回答。

Try-with-resources 仅适用于 Java 7 中实现AutoCloseable接口的资源。所以我的第一个建议是让您检查 APISapConnectSapApi(无论它们是什么)以确定是否是这种情况。

于 2015-03-26T10:26:27.597 回答
0

一种猜测:可能connect返回 SapApi 的子类或代理类。close如果未进行任何更改,则覆盖不执行任何操作,否则仅调用super.close().

我会给出答案,因为即使没有调用任何方法,AutoCloseable 也可以工作。

于 2015-03-26T11:46:51.520 回答