2014-02-11 4 views
4

У меня есть метод, который удаляет некоторые файлы:Может ли операция терминала (например, forEach) проверять исключения?

void deepDelete(Path root) { 
    Files.walk(root) 
      .filter(p -> !Files.isDirectory(p)) 
      .forEach(p -> { try { Files.delete(p); } 
          catch (IOException e) { /* LOG */ } 
      }); 
} 

/поймать блок попытки снижает читаемость операции, особенно по сравнению с использованием эталонного метода:

void deepDelete(Path root) throws IOException { 
    Files.walk(root) 
      .filter(p -> !Files.isDirectory(p)) 
      .forEach(Files::delete); //does not compile 
} 

К сожалению, этот код не компиляции.

Есть ли способ применить действие, которое выбрасывает проверенные исключения в терминальной операции и просто «реконструирует» любые исключения?

Я понимаю, что я мог написать оболочку, которая преобразует проверенное исключение в исключение, но, по возможности, я предпочитаю использовать методы в JDK.

+3

Видимо, Java 8 удаляется от исключений _checked_. Почти все вновь введенные исключения _unchecked_, а недавно введенные методы используют _unchecked_ exceptions, например. [Files.list] (http://download.java.net/jdk8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path-) выдает [UncheckedIOException] (http : //download.java.net/jdk8/docs/api/java/io/UncheckedIOException.html). – nosid

+0

@nosid: Не удается увидеть общий переход от отмеченных исключений. Только * потоковые операции * будут бросать 'UncheckedIOException' по той же причине, которая обсуждалась в этом вопросе: API потока не позволяет бросать проверочное' IOException'. Если перед построением потока происходит 'IOException', оно выбрано традиционно. – Holger

ответ

1

Насколько я могу судить: нет. Я использую this techempower article в качестве моего руководства java8, и он довольно явный (см. Раздел, озаглавленный «Прозрачность исключений»).

0

Если объявить этот метод:

@SuppressWarnings("unchecked") 
static <T extends Throwable> RuntimeException sneakyThrow(Throwable t) throws T { 
    throw (T)t; 
} 

Тогда вы можете сделать:

try { 
    Files.delete(p); 
} catch (IOException e) { 
    throw sneakyThrow(e); 
} 

Это обходит проверенные правила исключения и выбрасывает сырье IOException без упаковки, хотя вы все равно должны поймать его & ретрол. Я не говорю, что это хорошая идея, но это идея.