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.
The exception Supplier function is passed as a parameter. Syntax: public <X extends Throwable> double orElseThrow(Supplier<X> exceptionSupplier) throws X extends Throwable. Parameters: This method accepts one parameter exceptionSupplier which is the supplying function that produces an exception to be thrown.
Simply put, if the value is present, then isPresent() would return true, and calling get() will return this value. Otherwise, it throws NoSuchElementException. There's also a method orElseThrow(Supplier<? extends X> exceptionSupplier) that allows us to provide a custom Exception instance.
It's not possible to both throw an exception and return a value from a single function call.
If you would do that, you wouldn't be able to use it as a Supplier
as it would only throw UnsupportedOperationException.
Considering the above, why not create a new interface and declare the getWithIO
method in it?
@FunctionalInterface public interface SupplierWithIO<T> { public T getWithIO() throws IOException; }
Perhaps some things are better of as old-style Java interfaces? Old-style Java isn't gone just because there's Java 8 now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With