我正在编写一个程序,需要处理具有许多包装数字变量的对象,如Long,Double,Integer等。如何安全地对这些变量执行数值运算而无需在任何地方放置 >
我希望这是几乎每个Java程序员必须迟早要处理的事情,所以我很惊讶没有数百个关于该主题的博客文章和SO问题。
我目前的解决方案是通过以下方法过滤所有数字:
private static safelyUnbox(Integer i) {
return i == null ? 0 : i.intValue();
}
...
sumVariable += safelyUnbox(stupidObject.getNumberOfWhatever());
答案 0 :(得分:5)
Java 8为检查null
提供了一个很好的替代方案。如果Integer(例如)可能有也可能没有值,那么您可以将其声明为Optional<Integer>
。 Optional
类有很多有用的实用程序,用于返回默认值,抛出异常,检查值是否存在等。
声明Optional<Integer>
的好处在于,您正在向读者清楚地表明“没有价值”。是一个合法的国家。任何维护代码的人别无选择,只能使用Optional
方法来决定如果值存在或不存在会发生什么。
另一方面,如果参数是必需的,那么最简单的选择就是在使用之前断言它不是null。
在我可能不存在某个值的情况下使用Optional
的最大好处是,您可以在假设null
始终是错误的情况下开始依赖您的代码。
Optional
甚至提供了一种将潜在的空变量转换为Optional
的简洁方法(例如,如果它传递给您,并且您无法控制其在输入时的值你的代码)。它的工作原理如下:
Optional<Integer> optVal = Optional.ofNullable(val);
然后,您可以像使用任何其他Optional
一样使用新变量。例如:
optVal.ifPresent(myList::add);
或者:
return optVal.orElse(27);
答案 1 :(得分:2)
你有一个非常具体的问题,并试图在不考虑它的情况下概括它。
这可能是空值无效的前提条件。在您的情况下,您在评论中说明它不是。但如果是的话,你应该处理它而不是隐藏它。
“安全”值可能不同。您之所以选择0
,是因为您要将这些数字相加,如果您乘以(或将其用作商数)会怎么样?这是您的safelyUnbox
方法没有的知识。
避免概括一切。对于您的情况,最好的代码就像:
for(Integer integ : myCollection) {
if (integ != null) {
sum += integ;
}
}
其他每种情况都有自己的,最合适的解决方案。将其与
进行比较for(Integer integ : myCollection) {
sum += safeUnboxThatDefaultsto0(integ);
}
或
for(Integer integ : myCollection) {
sum += safeUnbox(integ, 0);
}
使用这种方法你赢了什么?
答案 2 :(得分:1)
您可以使用Google的番石榴图书馆Using and avoiding null
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
Optional
的最大优势不在于readability
:优点是它的白痴证明。如果您希望程序完全编译,它会强制您主动考虑缺席情况,因为您必须主动解包可选并解决该情况。 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() );
}