未经检查的调用 ifPresent 检查,为啥? [复制]

Posted

技术标签:

【中文标题】未经检查的调用 ifPresent 检查,为啥? [复制]【英文标题】:Unchecked call to ifPresent inspection, why? [duplicate]未经检查的调用 ifPresent 检查,为什么? [复制] 【发布时间】:2019-12-25 13:35:24 【问题描述】:

我的代码:

public static boolean searchLineOnLogFile(String...keywords)

    Collection select = null;

    try (final Stream<String> lines = Files.lines(get(getServerLog().toString())))
    
        select = CollectionUtils.select(lines.collect(Collectors.toCollection(LinkedList::new)),
                new Predicate()
                
                    public boolean evaluate(Object object)
                    
                        String line = (String) object;
                        return Arrays.stream(keywords).allMatch(line::contains);
                    
                );

     catch (IOException e)
    
        e.printStackTrace();
        Assert.fail(e.getMessage());
    

    select.stream().findFirst().ifPresent(firstLine -> LogAutomation.info((String)firstLine));

    return select.size() > 0;
    

select.stream().findFirst().ifPresent(firstLine -> log.info((String)firstLine));

为什么我会收到“取消选中 isPresent 调用”检查?如何改进我的代码?

full inspection message

从我读到的所有想法都是避免空检查:

“所以不要写这样的东西:

if(optional.isPresent)
    doSomething(optional.get);

你可以写:

optional.ifPresent(val->doSomething(val));

或者如果您愿意:

optional.ifPresent(this::doSomething);

【问题讨论】:

您能分享一下您收到的确切警告吗?我猜问题出在(String)firstLine 并且警告与可选方法无关 向我们展示select的声明。 可能是因为您的select 变量已使用raw type 声明。 正如我所怀疑的,select 有一个 原始类型。将声明更改为Collection&lt;String&gt; select。其他人指出的仍然是正确的,您的异常处理......需要改进,因为在捕获异常后,您将继续使用select 成为null。但这不是编译器警告的原因。 除了使用raw type引起的编译器警告外,很扭曲,收集一个流到一个集合,无缘无故坚持LinkedList,然后使用第 3 方库方法CollectionUtils.select,终于再次获取流。您可以直接过滤原始流:Optional&lt;String&gt; o = lines.filter(line -&gt; Arrays.stream(keywords) .allMatch(line::contains)) .findFirst(); o.ifPresent(firstLine -&gt; LogAutomation.info((String)firstLine)); return o.isPresent();。无需收藏到LinkedList,无需第三方图书馆。 【参考方案1】:

您可以使用 Optional.ofNullable,正如 Butiri 所回答的那样。 您也可以使用 Objects.requireNonNullElse

在第二种情况下,如果为空,您可以定义默认值。 示例:

public class Main 

    public static void main(String[] args) 
        Collection<Integer> select = null;

        if (Math.random() > 0.5) 
            select = Arrays.asList(1, 2, 3);
        

        Objects.requireNonNullElse(select, Collections.singletonList(99)).stream().
                findFirst().
                ifPresent(e -> System.out.println("found: " + e));
    


【讨论】:

【参考方案2】:

警告是因为select 可以为空。可以通过Optional.ofNullable修复

Optional.ofNullable(select).stream().findFirst().ifPresent(firstLine -> LogAutomation.info((String) firstLine));

【讨论】:

你是对的,select 可以是null,这可能会导致问题。但这不是 unchecked 警告的原因。除此之外,在可选项上调用 .stream() 需要 Java 9,并且与在包含的集合上调用 stream() 不同。

以上是关于未经检查的调用 ifPresent 检查,为啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

用 Optional#ifPresent 替换空检查的好处 [重复]

Java中的使用了未经检查或不安全的操作

Linux Kernel 4.2.x:为啥检查时预期的系统调用地址与实际地址不匹配?

使用未经检查或不安全的操作,使用 -Xlint 重新编译:未检查详细信息 [重复]

JLS 的哪些部分证明能够像未经检查一样抛出已检查异常?

生成签名 APK 时未经检查的演员表