Skip to content

Java utilities to throw checked exceptions in a "sneaky" way.

License

Notifications You must be signed in to change notification settings

SimonHarmonicMinor/sneaky-java

Repository files navigation

Sneaky Java

Java utilities to throw checked exceptions in a "sneaky" way.

If you're tired of checked exceptions in lambdas, then this library is made for you! For example, take a look at this code snippet.

class MyClass {

  void doAction() {
    List<String> messageContents = getStringLines()
        .stream()
        .map(str -> {
          try {
            return objectMapper.readValue(str, MessageDTO.class);
          } catch (JsonProccesingException e) {
            throw new RuntimeException(e);
          }
        })
        .map(msg -> msg.getContent())
        .toList();
  }
}

It can be simplified with Sneaky.function.

class MyClass {

  void doAction() {
    List<String> messageContents = getStringLines()
        .stream()
        .map(Sneaky.function(
            str -> objectMapper.readValue(str, MessageDTO.class)
        ))
        .map(msg -> msg.getContent())
        .toList();
  }
}

This library has no dependencies.

The master branch provides the latest DEV-SNAPSHOT version. You can find the specific release version info by git tags.

Status

Build Status Javadoc Quality Gate Status Coverage Hits-of-Code checkstyle PMD MIT License

Quick Start

You need Java 8+ to use the library.

Please, use the latest release version Maven Central .

Maven:

<dependency>
  <groupId>com.kirekov</groupId>
  <artifactId>sneaky-java</artifactId>
  <version>x.y.z</version>
</dependency>

Gradle:

implementation 'com.kirekov:sneaky-java:x.y.z' 

Usage

The library provides wrappers for native Java functional interfaces.

Suppose we want to declare a Predicate to use it within Stream API. Here we got isValueAllowed method.

class Predicates {

  boolean isValueAllowed(String value) throws IOException {
    // filtering logic  
  }
}

Sadly, the underlined statement won't compile.

class MyService {

  void doJob() {
    // compile error happens here
    Predicate<String> predicate = (value) -> isValueAllowed(value);
    ...
  }
}

Because isValueAllowed may throw IOException which is a checked exception. Whilst Predicate declaration does not allow it. We can write a custom wrapper for this case.

class MyService {

  void doJob() {
    Predicate<String> predicate = (value) -> {
      try {
        return isValueAllowed(value);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    ...
  }
}

Though the solution it does work, it looks rather ugly. Fortunately, sneaky-java provides convenient factory methods for such cases.

import com.kirekov.sneaky.Sneaky;

class MyService {

  void doJob() {
    Predicate<String> predicate = Sneaky.predicate(
        value -> isValueAllowed(value)
    );
    ...
  }
}

Besides, sneaky predicates does not wrap checked exceptions with RuntimeException instance. Instead, it uses Java generic type erasure mechanism to rethrow checked exception ignoring compile errors. Here is the core idea.

class Sneaky {

  @SuppressWarnings("unchecked")
  public static <T extends Exception> void throwUnchecked(Exception exception) throws T {
    throw (T) exception;
  }
}

The sneaky-java provides wrappers for the common Java functional interfaces.

  1. PredicateSneaky.predicate
  2. BiPredicateSneaky.biPredicate
  3. FunctionSneaky.function
  4. BiFunctionSneaky.biFunction
  5. ConsumerSneaky.consumer
  6. BiConsumerSneaky.biConsumer
  7. SupplierSneaky.supplier

About

Java utilities to throw checked exceptions in a "sneaky" way.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages