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.
You need Java 8+ to use the library.
Please, use the latest release
version
.
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' 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.
- Predicate
—
Sneaky.predicate - BiPredicate
—
Sneaky.biPredicate - Function
—
Sneaky.function - BiFunction
—
Sneaky.biFunction - Consumer
—
Sneaky.consumer - BiConsumer
—
Sneaky.biConsumer - Supplier
—
Sneaky.supplier