Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to declare that a Supplier<T> needs to throw an Exception?

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.

like image 735
skiwi Avatar asked Mar 27 '14 12:03

skiwi


People also ask

What is exception supplier?

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.

How do you throw an exception in optional?

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.

Can you throw an exception and return something?

It's not possible to both throw an exception and return a value from a single function call.


1 Answers

  • 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.

like image 153
Simon Forsberg Avatar answered Sep 19 '22 19:09

Simon Forsberg