Подтвердить что ты не робот

Как использовать Throwables.propagateIfInstanceOf() из Google Guava?

Пример javadoc

  try {
    someMethodThatCouldThrowAnything();
  } catch (IKnowWhatToDoWithThisException e) {
    handle(e);
  } catch (Throwable t) {
    Throwables.propagateIfInstanceOf(t, IOException.class);
    Throwables.propagateIfInstanceOf(t, SQLException.class);
    throw Throwables.propagate(t);
  }

не очень конкретный. Как выглядела бы настоящая программа? Я действительно не понимаю цели методов Throwables.propagateIfInstanceOf(Throwable, Class), propagate(), propagateIfPossible(). Когда я их использую?

4b9b3361

Ответ 1

Цель этих методов - предоставить удобный способ справиться с проверенными исключениями.

Throwables.propagate() является сокращением общей идиомы перебора проверенного исключения, заключенного в непроверенный (чтобы избежать объявления его в предложении throws).

Throwables.propagateIfInstanceOf() используется для восстановления проверенных исключений, как если бы их типы были объявлены в throws в методе метода.

Другими словами, рассматриваемый код

public void doSomething() 
    throws IOException, SQLException {

    try {
        someMethodThatCouldThrowAnything();
    } catch (IKnowWhatToDoWithThisException e) {
        handle(e);
    } catch (Throwable t) {
        Throwables.propagateIfInstanceOf(t, IOException.class);
        Throwables.propagateIfInstanceOf(t, SQLException.class);
        throw Throwables.propagate(t);
    }  
}

является сокращением для следующего кода:

public void doSomething() 
    throws IOException, SQLException {

    try {
        someMethodThatCouldThrowAnything();
    } catch (IKnowWhatToDoWithThisException e) {
        handle(e);
    } catch (SQLException ex) {
        throw ex;
    } catch (IOException ex) {
        throw ex;
    } catch (Throwable t) {
        throw new RuntimeException(t);
    }  
}

См. также:

Ответ 2

Я просмотрел документацию Guava Throwables, и я не нашел их действительно полезными. Использование throw new RuntimeException (e) проще понять, чем Throwables.propagate(), в сценарии, в котором вы хотите выбросить исключенную исключение, завершая проверенное исключение.

Ответ 3

Один из сценариев, которые я могу предоставить всем, кто найдет это полезным, - это если у вас есть метод, который обертывает все выброшенные исключения, тогда это можно использовать для разворачивания/включения причины в конкретное исключение.

Пример: get метод в Guava LoadingCache заверяет все отмеченные исключения в ExecutionException. В документации указано, что исключение можно проверить с помощью getCause().

Здесь Throwables.propagateIfInstanceOf может использоваться для передачи определенных исключений для вызывающего метода для обработки, если мы знаем, что cache.get() будет генерировать эти исключения (возможно, специфичные для LoadCache, но если значение является misisng, кеш пытается загрузить значение, которое может выдавать проверенные исключения).

public String getCacheValue(String key) throws SQLException{
  try{
       return cache.get(key);
  }catch(ExecutedException ex){
       Throwables.propagateIfInstanceOf(ex.getCause(), SQLException.class);
       Throwables.propagate(ex);
  }
}