So I am trying to refactor the following code:
/**
* Returns the duration from the config file.
*
* @return The duration.
*/
private Duration durationFromConfig() {
try {
return durationFromConfigInner();
} catch (IOException ex) {
throw new IllegalStateException("The config file (\"" + configFile + "\") has not been found.");
}
}
/**
* Returns the duration from the config file.
*
* Searches the log file for the first line indicating the config entry for this instance.
*
* @return The duration.
* @throws FileNotFoundException If the config file has not been found.
*/
private Duration durationFromConfigInner() throws IOException {
String entryKey = subClass.getSimpleName();
configLastModified = Files.getLastModifiedTime(configFile);
String entryValue = ConfigFileUtils.readFileEntry(configFile, entryKey);
return Duration.of(entryValue);
}
I came up with the following to start of with:
private <T> T getFromConfig(final Supplier<T> supplier) {
try {
return supplier.get();
} catch (IOException ex) {
throw new IllegalStateException("The config file (\"" + configFile + "\") has not been found.");
}
}
However, it does not compile (obviously), as Supplier
cannot throw an IOException
. Is there any way I can add that to the method declaration of getFromConfig
?
Or is the only way to do it like the following?
@FunctionalInterface
public interface SupplierWithIO<T> extends Supplier<T> {
@Override
@Deprecated
default public T get() {
throw new UnsupportedOperationException();
}
public T getWithIO() throws IOException;
}
Update, I just realised that the Supplier
interface is a really simple one, as in it has only the get()
method. The original reason why I extended Supplier
is to preverse the basic functionality, like the default methods for example.
throws Exception
signature in the functional interface and wrap it into anuncheckedCall
lambda, which propagates the exception without checking (usingsneakyThrow
). – SistrunksneakyThrow
. – SistrunkuncheckedCall
andsneakyThrow
are in your example? – Mathisstatic <T> T uncheckCall(Callable<T> callable) { try { return callable.call(); } catch (Exception e) { return sneakyThrow(e); }
.sneakyThrow
is a standard idiom and can be found for example here: #14039149 – Sistrunk