当前位置: 首页 > 知识库问答 >
问题:

如何安全地处理Java的包装原语

盖弘毅
2023-03-14

我正在编写一个程序,该程序需要处理具有许多包装数字变量的对象,例如Long,Double,Integer等。如何安全地对这些操作执行数值运算,而不必到处放置空检查?

我认为这是几乎每个Java程序员迟早都必须处理的事情,所以我很惊讶没有数百篇关于这个主题的博客帖子和问题。

我目前的解决方案是通过以下方法过滤所有数字:

private static safelyUnbox(Integer i) {
    return i == null ? 0 : i.intValue();
}
...
sumVariable += safelyUnbox(stupidObject.getNumberOfWhatever());

共有3个答案

辛可人
2023-03-14

您可以使用Google的Guava库,使用和避免null

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5

可选的最大优势不在于易读性:优势在于它的防白痴性。如果您希望您的程序编译,它会迫使您主动考虑缺失的大小写,因为您必须主动打开可选并解决该大小写。Null使简单地忘记事情变得令人不安。

假设在这种情况下:

String meterReading=getValueFromRemoteSite();
System.out.println(meterReading.toLowerCase()); //Chances for NPE

但是使用可选场景是不同的

Optional meterReading = Optional.of(getValueFromRemoteSite(););
if( meterReading.isPresent() )
{
   System.out.println( meterReading.get() );
}  
越风史
2023-03-14

你有一个非常具体的问题,并试图在不考虑它的情况下概括它。

>

  • 这可能是 null 值无效的前提条件。在你的情况下,你在评论中声明它不是。但如果是这样,你应该处理它而不是隐藏它。

    “安全”值可能不同。您选择<code>0</code>是因为您要将数字相加,如果您是在乘法(或将其用作商),会怎么样?这是您的<code>safelyUnbox</code>方法所不具备的知识。

    避免泛化一切。对于您的情况,最好的代码如下所示:

    for(Integer integ : myCollection) {
      if (integ != null) {
        sum += integ;
      }
    }
    

    每种情况都有自己最合适的解决方案。与

    for(Integer integ : myCollection) {
      sum += safeUnboxThatDefaultsto0(integ);
    }
    

    for(Integer integ : myCollection) {
      sum += safeUnbox(integ, 0);
    }
    

    你用这个方法赢了什么?

  • 商飞龙
    2023-03-14

    Java 8 提供了一个很好的替代方法来检查 null。如果一个整数(例如)可能有也可能没有值,那么你可以将其声明为可选

    声明<code>可选的优点

    另一方面,如果参数是强制的,那么最简单的选择就是在使用它之前断言它不为空。

    每当值可能不存在时使用可选的最大优势(在我看来)是您可以开始依赖您的代码,前提是null始终是错误的。

    可选甚至提供了一种将潜在的空变量转换为可选的简洁方法(例如,如果它已传递给您并且您在输入代码时无法控制它的值)。它是这样工作的:

    Optional<Integer> optVal = Optional.ofNullable(val);
    

    然后,您可以用与任何其他<code>可选</code>相同的方式使用新变量。例如:

    optVal.ifPresent(myList::add);
    

    艺术

    return optVal.orElse(27);
    

     类似资料:
    • 我试图安装flake8包使用pip3,它似乎拒绝安装,因为已经安装在一个本地位置。 如何强制全局安装(系统级)? 请注意,我更喜欢一个通用的解决方案(应该在Debian、OSX甚至Windows上工作),一个应该在任何平台上使用的解决方案,所以我不想自己指定目标。 出于某种奇怪的原因,它的行为就像我已经指定了,而在我的情况下,我没有指定。 我能够在全球范围内安装包的唯一方法是首先删除它,然后在此之

    • 问题内容: 我在Windows7上安装grunt,node,npm,bower和grunt-cli。 说明说我应该为全局运行带有-g标志的安装命令。 安装后如何检查是否使用了-g标志。卸载它们并重新安装将花费大量时间。 问题答案: 使用带有标志的命令来查看全局安装的所有软件包: 要检查是否在全球范围内安装了特定的软件包,可以提供软件包的名称(在这种情况下),如下所示: 或者您可以使用来过滤软件包名

    • 相应的 Composer 命令,包括exec、install和update,它们都允许在你的机器上运行第三方代码。这来自 Composer 的「插件」和「脚本」功能。插件和脚本可以完全访问运行 Composer 的用户账号。因此,强烈建议避免使用 root 账号运行 Composer。 在安装或更新包期间,为了只让 Composer 代码、而非第三方代码运行,你可以使用以下语法禁用插件和脚本: c

    • Spray HTTP服务器的示例使用似乎使服务器按顺序而不是并发地处理请求变得非常容易。这是正确的,因为示例显示了作为一次处理一个请求的执行元实现的路由对象(FacePalm?**)。这似乎是一个普遍的问题。 有没有一种方法使用Spray.Routing在到达路由之前分叉执行? **由于路由通常是一个无状态的操作,所以让路由器和参与者看起来并没有什么好处,对吗? 对于我使用过的每一个其他webse