What is the recommended way to handle (or suppress) exceptions thrown by an AutoCloseable?

StackOverflow https://stackoverflow.com/questions/20863919

  •  23-09-2022
  •  | 
  •  

Domanda

I am upgrading some existing APIs that take Iterables to be AutoCloseable-sensitive. For example, given:

/**
 * @throws NoSuchElementException
 */
public static <T> T getOne(Iterable<T> iterable) {
  return iterable.iterator().next();
}

I would like the method to close the iterator if it is closable. Here's what I've got so far:

/**
 * @throws NoSuchElementException
 */
public static <T> T getOne(Iterable<T> iterable) {
  Iterator<T> iterator = iterable.iterator();
  try {
    return iterable.iterator().next();
  } finally {
    if (iterator instanceof AutoCloseable) {
      try {
        ((AutoCloseable) iterator).close();
      } catch (Exception ignored) {
        // intentionally suppressed
      }
    }
  }
}

Given how the JDK documentation refers to Throwable.getSuppressed(), should this code be doing something akin to the following?

      } catch (Exception x) {
        RuntimeException rte = new RuntimeException("Could not close iterator");
        rte.addSuppressed(x);
        throw rte;
      }
È stato utile?

Soluzione

I think the best thing to do is simply piggy-back off the try-with-resources construct if you find that you have an AutoCloseable, something like this:

/**
 * @throws NoSuchElementException
 */
public static <T> T getOne(Iterable<T> iterable) {
  Iterator<T> iterator = iterable.iterator();
  if (iterator instanceof AutoCloseable) {
    try (AutoCloseable c = (AutoCloseable) iterator) {
      return iterator.next();
    }
  } else {
    return iterator.next();
  }
}

Then the language-level construct will take care of exceptions (including in the close method) in the correct way.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top