Поскольку Java 7 вы должны использовать примерочный с-ресурсами
try(Scanner sc1 = new Scanner("");
Scanner sc2 = new Scanner("");
Scanner sc3 = new Scanner("")){
}
//all scanners get closed implicitly
Так что вам не нужны какая-либо кода.
Проблема со всеми конструкциями для каждого или потока состоит в том, что - теоретически - если первый close()
сбой исключается при вызове метода базового источника close()
, следующие сканеры не будут закрыты. Реализация Scanner.close()
улавливает любое исключение IOException, но не может быть другого исключения.
Консоль try-with-resources имеет дело с этим, петли этого не делают.
EDIT: В то время как Ваш вопрос направлен на более общий подход, указанное решение было ответом на вашей конкретной проблемы: иметь дело с AutoCloseable
ресурсов, которые в любом случае должны быть использованы с пытаясь угадать с-ресурсами, не требуя специальной обработки метода закрытия вообще (= кратчайшее решение вашей конкретной проблемы).
Что касается более общего вопроса о работе с произвольными элементами (которые нет ресурсов), Java имеет по крайней мере два варианта:
Создание списка из массива/списков параметров и перебрать его
for(YourItemType item : Arrays.asList(your,items,here)) {
//do something
}
Создание потока из массива/списков параметров и применять функции к нему
Stream.of(your,items,here).forEach(item -> { doSomething});
конечно, «DoSomething» может быть заменена ссылкой методом
Stream.of(your,items,here).forEach(this::myMethod);
...
void myMethod(YourItemType item){
//doSomething
}
Проблема с этим подходом заключается в том, что проверенное исключение должно рассматриваться явно в лямбда-выражениях. Давайте брать пример выше, и пусть myMethod
бросить проверяемое исключение
void myMethod(YourItemType item) throws Exception
в том случае, если ваш поток заявление должен был бы выглядеть
Stream.of(your,items,here).forEach(item -> {
try {
myMethod(item);
} catch (Exception e){
//omit or throw new RuntimeException(e);
};
это не выглядит, что приятно.Но мы могли бы поместить лямбда-тело в отдельный метод.
void myMethodQuietly(YourItemType item) {
try {
myMethod(item);
}catch(Exception e){
//omit or throw new RuntimeException(e);
}
}
Stream.of(your,items,here).forEach(this::myMethodQuietly);
Этот подход может представлять интерес для вашей конкретной проблемы с ресурсами. Мы можем поставить все это в CompositeAutoCloseable
, который берет ресурсы, созданные за пределами класса, что все должны быть закрыты безопасно на вызов close()
public class CompositeAutoCloseable implements AutoCloseable {
private List<Closeable> resources;
public CompositeAutoCloseable(Closeable... resources) {
this.resources = Arrays.asList(resources);
//you could use a stream here too
}
@Override
public void close() {
this.resources.stream().forEach(this::closeQuietly);
}
void closeQuietly(Closeable res) {
if(res == null) {
return;
}
try {
res.close();
}catch(Exception e){
//omit
}
}
}
И когда у вас есть такой вспомогательный класс, вы можете использовать его снова примерочный с -Ресурсы.
try(CompositeAutoCloseable cac = new CompositeAutoCloseable(sc1,sc2,sc3)) {
//do something
}
Я оставляю это до вас, чтобы решить, если это имеет смысл, по сравнению с щётками раствора;)
http://stackoverflow.com/questions/24390463/java-8-stream-and-operation-on-arrays – Tschallacka
Чтобы ответить на общий вопрос: 'Stream.of (sc1, sc2, sc3) .forEach (Scanner :: close); ', но для этого конкретного случая [послушайте Джеральда Мюке] (http://stackoverflow.com/a/37023624/2711488) – Holger