Можно ли отказаться от try-with-resources?
Предисловие: для моков статических методов в Mockito существует интерфейс MockedStatic, наследующийся от AutoClosable. Соответственно, его обычно использьзуют вот так:
try (MockedStatic<SomeUtil> staticMockedSomeUtil = new MyClass()) {
// некоторая логика
}
Я хочу заметить, что методы MockedStatic не выбрасывают проверяемых исключений, в том числе и метод close().
В связи с этим, мне приходит мысль отказаться от использования блока try-with-resources и сделать примерно вот такую утилиту, которую я буду использовать в тестах:
public class TestUtil {
private final List<MockedStatic<?>> activeResources = new ArrayList<>();
public <T> MockedStatic<T> mock(Class<T> clazz) {
MockedStatic<T> mockedClass = MockedStatic.mockStatic(clazz);
activeResources.add(mockedClass);
return mockedClass;
}
public void closeAll() {
activeResources.forEach(resource -> resource.close());
}
}
Во-первых в тестах можно будет отказаться от использования try-with-resources, код станет чище. Во-вторых я хочу написать единый утильный класс для тестирования, которым будет пользоваться вся команда.
Таким образом, вопрос следующий: а нужен ли мне try-with-resources, если класс для доступа к ресурсу не бросает проверяемых исключений ни при работе, ни при закрытии?
Ответы (2 шт):
можно (особенно в тестах).
try-with-resources это "синтактический сахар", который упрощает работу с AutoClosable автоматически вызывая close().
Если Вы предпочитаете другой (достаточно надежный) способ освобождения ресурсов (вызова close()), то вполне можете обойтись без автоматического освобождения.
На мой вопрос можно ответить, если посмотреть, во что компилируется try-with-resources.
Вот здесь есть пример того, как такой код:
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
baos.flush();
}
компилируется вот в такой:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Throwable var2 = null;
try {
baos.flush();
} catch (Throwable var11) {
var2 = var11;
throw var11;
} finally {
if (baos != null) {
if (var2 != null) {
try {
baos.close();
} catch (Throwable var10) {
var2.addSuppressed(var10);
}
} else {
baos.close();
}
}
}
Можно видеть, что ничего сверхъестественного под капотом не происходит. Конкретно в моём случае с MockedStatic можно обойтись без try-with-resources, разумеется, если обеспечить надёжный механизм закрытия.