For example for this code:
List<Class> classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> Class.forName(className))
.collect(Collectors.toList());
This code runs fine now. but, assume we have a empty list in stream and we have tons of operations to the stream. It could get NullPointer exceptions and etc. I find it's also hard to try-catch for this kind of statement. What's the right way to handle exception for this?
You do not need to check for nulls. If you have an empty stream all operations will be skipped:
Stream.of("hello")
.filter(e => "world".equals(e)) // empties the stream
.foreach(System.out::println); // no NullPointer, no output
Exception handling is possible in mapper:
List<Class<?>> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> {
try {
return Class.forName(className);
} catch (Exception e) {
throw new YourRuntimeException();
}
})
.collect(Collectors.toList());
If you want exceptions to be ignored, then I suggest to map to Optional
s.
List<Class<?>> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> {
try {
return Optional.of(Class.forName(className));
} catch (Exception e) {
return Optional.<Class<?>>empty();
}
})
.filter(Optional::isPresent) // ignore empty values
.map (Optional::get) // unwrap Optional contents
.collect(Collectors.toList());
Please also have a look at How can I throw CHECKED exceptions from inside Java 8 streams? for a more detailed discussion about Class.forName
in combination with java 8 streams.
Your question is a bit strange. You are claiming “This code runs fine now” whereas it should generate compile-time errors as you are not handling the checked exception declared by Class.forName
. Further you are talking about empty lists, but in your code, no lists are involved. The same applies to your reference to NullPointerException
as your code does not produce null
at any place.
Most probably, you are talking about a code which catches the ClassNotFoundException
and handles it by returning null
. You should never do this. If you want to filter out failures, you may do it this way:
List<Class<?>> classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.flatMap(className -> {
try {
return Stream.of(Class.forName(className));
} catch (ClassNotFoundException ex) {
// recommended: insert logging statement here
return Stream.empty();
}
})
.collect(Collectors.toList());
This way, no element will be generated in the case of an exception and you don’t have to do additional error handling downstream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With