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