在Java8中,在链式语句中检查null或异常的正确方法是什么?

x759pob2  于 2022-12-25  发布在  Java
关注(0)|答案(4)|浏览(150)

例如,对于此代码:

List<Class> classes = 
        Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
              .map(className -> Class.forName(className))
              .collect(Collectors.toList());

这段代码现在运行得很好。但是,假设我们在流中有一个空列表,并且我们有大量的流操作。它可能会得到NullPointer异常等。我发现对于这种语句,try-catch也很难。处理这种异常的正确方法是什么?

hts6caw3

hts6caw31#

你的问题有点奇怪。你声称“这段代码现在运行良好”,但它应该生成编译时错误,因为你没有处理Class.forName声明的检查异常。此外,你谈论的是空列表,但在你的代码中,没有涉及列表。这同样适用于你对NullPointerException的引用,因为你的代码在任何地方都没有生成null
最有可能的情况是,您正在讨论的代码捕获ClassNotFoundException并通过返回null来处理它。您永远不应该这样做。如果您想过滤掉失败,您可以这样做:

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());

这样,在发生异常的情况下不会生成任何元素,您也不必在下游进行额外的错误处理。

6yoyoihd

6yoyoihd2#

我们也可以使用资源试用,

try(List<Class> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String"))
{
 List<Class> classes = Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")        
              .map(className -> Class.forName(className))
              .collect(Collectors.toList()); 
}

应添加throws Exception以处理

qjp7pelc

qjp7pelc3#

我不确定你所说的“在流中有一个空列表”是什么意思,但是如果你想安全地处理流中空值的可能性,你可以用途:

List<Class> classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String", null)
    .filter(Objects::nonNull)
    .map(className -> {
      try {
        return Class.forName(className);
      } catch (ClassNotFoundException e) {
        System.out.println("No class found for: " + className);
        return null;
      }
    })
    .filter(Objects::nonNull)
    .collect(Collectors.toList());
4c8rllxm

4c8rllxm4#

不需要检查空值。如果流为空,则将跳过所有操作:

Stream.of("hello")
      .filter(e => "world".equals(e)) // empties the stream
      .foreach(System.out::println); // no NullPointer, no output

Map器中可能存在异常处理:

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());

如果您希望忽略异常,那么我建议Map到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());

也请看一下How can I throw CHECKED exceptions from inside Java 8 streams?,以获得关于Class.forName与java8流结合使用的更详细的讨论。

相关问题