繁体   English   中英

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

[英]What's the right way to check null or check exceptions in a chained statement in Java 8?

例如对于这段代码:

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

这段代码现在运行良好。 但是,假设我们在流中有一个空列表,并且我们对流进行了大量操作。 它可能会出现 NullPointer 异常等。我发现这种语句也很难尝试捕获。 为此处理异常的正确方法是什么?

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

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

映射器中可以进行异常处理:

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

如果你想要忽略异常,那么我建议映射到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());

另请参阅如何从Java 8流中抛出CHECKED异常? 有关Class.forName与java 8流的组合的更详细讨论。

你的问题有点奇怪。 您声称“此代码现在运行正常”,而它应该生成编译时错误,因为您没有处理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());

这样,在异常的情况下不会生成任何元素,并且您不必在下游执行其他错误处理。

我们也可以使用 try-with-resources,

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来处理

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM