Skip to content

API Examples

zleonov edited this page Dec 6, 2023 · 10 revisions

API Examples

This document details the basic use cases of Unchecked Java.

Initialization of static fields

Let's say we were defining a private static final url field. You may start with the following:

private static final URL GOOGLE_NEWS = new URL("https://news.google.com");

Your IDE would quickly inform you about an uncaught exception. The problem is that new URL throws a MalformedURLException which is a checked-exception. At this point most people just revert to using a String:

private static final String GOOGLE_NEWS = "https://news.google.com";

In the grand scheme of things, this works just fine, with the likely risk that you'll create multiple redundant URL news = new URL(GOOGLE_NEWS) instances in different parts of your code. But what if you wanted to enforce a singleton URL instance?

private static final URL GOOGLE_NEWS;

static {
    try {
        GOOGLE_NEWS = new URL("https://news.google.com");
    } catch (final MalformedURLException e) {
        throw new AssertionError(e); // cannot happen
    }
}

This is perfectly functional if not cumbersome and verbose. Using Unchecked Java we can accomplish this with a single line of code:

private static final URL GOOGLE_NEWS = uncheckedGet(() -> new URL("https://news.google.com"));

Don't forget to import static software.leonov.common.util.function.CheckedSupplier.uncheckedGet;

Note

Even if an error occurs initializing a static field, we are not worried about circumventing Java's exception handling mechanisms with Unchecked Java because all class initialization errors will be suppressed under a java.lang.ExceptionInInitializerError.

Functional APIs

Java's functional interface types are not compatible with lambdas that throw checked exceptions. Consider the following example:

final List<URL> resources = Stream.of("https://www.google.com", "https://www.yahoo.com").map(URL::new).collect(Collectors.toList());

The Stream.map method accepts a java.util.function.Function object whose apply method does not throw a checked exception. We are forced to refactor the code and rethrow the MalformedURLException as a RuntimeException in order to get it to compile:

final List<URL> resources = Stream.of("https://www.google.com", "https://www.yahoo.com").map(t -> {
        try {
            return new URL(t);
        } catch (final MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }).collect(Collectors.toList());

With Unchecked Java the example above can be re-written in a compact and concise manner:

final List<URL> resources = Stream.of("https://www.google.com", "https://www.yahoo.com").map(evalUnchecked(URL::new)).collect(Collectors.toList());

This time we import static software.leonov.common.util.function.CheckedFunction.evalUnchecked;

Let's look at another example. Suppose you want to sort files according to their size in bytes:

final List<Path> files = ...
        
files.sort(Comparator.comparingLong(value -> {
    try {
        return Files.size(value);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}));

With Unchecked Java we can write:

final List<Path> files = ...

files.sort(evalUnchecked(comparingLong(Files::size)));

This time we have to import static software.leonov.common.util.function.CheckedComparator.evalUnchecked; and import static software.leonov.common.util.function.CheckedComparator.comparingLong;

Clone this wiki locally