FindBugs - 装箱值被取消装箱,然后立即重新装箱

FindBugs - Boxed value is unboxed and then immediately reboxed

在以下代码片段中获取装箱值已拆箱然后立即重新装箱错误。 请帮助我了解问题出在哪里?

     public Integer convert(String str) {
        String result = Optional.ofNullable(str)
            .filter(sStr -> sStr.length() != 0)
            .map(sStr -> sStr.substring(0, sStr.length() - 1))
            .orElse(StringUtils.EMPTY);
        return result.isEmpty() ? 1 : Integer.valueOf(result);
     }

FindBugs 和 SpotBugs 显示警告:已装箱的值被取消装箱,然后立即重新装箱 (BX_UNBOXING_IMMEDIATELY_REBOXED) 当规则等级 >=启用了 18 个。(至少在 SpotBugs 中默认情况下未启用)

三元运算符 (?:) 与 boxing/unboxing 结合使用时有点棘手。如果 str 不为空,您的最后一行代码将:

  1. 调用方法Integer.valueOf(String)

  2. 此方法调用 Integer.valueOf(parseInt(s, 10));int 值转换为 Integer 对象(第一次装箱)

  3. 由于您在三元运算符的第一部分使用了 int 值,因此 returned Integer 对象被转换为 int 值(拆箱)

  4. 最后 int 值在 return(第二次装箱)

    之前转换为 Integer 对象

总结:代码创建了两个 Integer 对象,而不是一个 Integer 对象。在大多数情况下,这并不是真正的问题。因此,相应的 FindBug 规则只有 18 级,默认情况下处于禁用状态。当您的代码在高负载场景中频繁执行时,不必要的对象创建可能会出现问题,短时间内创建数百万个短期对象会对垃圾收集器产生负面影响。

您可以通过将 1 替换为 (Integer)1Integer.valueOf(1) 来避免此警告。两者都将产生相同的字节码并避免不必要地创建第二个 Integer 对象。