Java null检查Javabean嵌套属性

时间:2015-07-14 16:19:58

标签: java jsf nullpointerexception

我正在使用BigDecimal计算并阅读它,检查null是否比使用try catch包围更好。例如:

private BigDecimal computeSpringRateBoltWasher() {
    if (boltWasher.getMaterial().getElastic_modulus() != null) {
      BigDecimal term1 = boltWasher.getMaterial().getElastic_modulus().multiply(BigDecimal.TEN);
        // other equations 
      return results;
    }
   return null;
}

但是在这里我得到一个nullPointerException,因为螺栓垫圈的材料是空的。如何在弹性模量上干净地检查材料上的零点?

归结为这样的事情吗?我在这种方法中还有一些其他属性,我需要检查它,它可能会变得混乱。

private BigDecimal computeSpringRateBoltWasher() {
    if (boltWasher.getMaterial() != null) {
       if (boltWasher.getMaterial().getElastic_modulus() != null) {

修改

我返回null的原因是在facelets页面中,如果没有输入所有输入值,结果页面会显示一个? (在OmniFaces coalese的帮助下)

Bolt Washer Spring Rate = 
<h:outputText value="#{of:coalesce(controller.boltAnalysis.jointStiffness.boltWasherSpringRate, '?')}">
<f:convertNumber minFractionDigits="7" />
</h:outputText>

3 个答案:

答案 0 :(得分:1)

简化您的代码,(将boltWasher.getMaterial()解压缩到一个新变量,使您的代码更具可读性)。 如果您正在编写API或提供验证的应用程序,那么Apache commons就派上用场了。我会这样做,请参阅代码中的注释:

import org.apache.commons.lang3.Validate;

import java.math.BigDecimal;

/**
 * Any
 */
 public class Any {

    private BigDecimal anything;

    public void setAnything(BigDecimal anything){
            this.anything = anything;
    }

    /**
     * computeSpringRateBoltWasher. Explain what this method is intended to do.
     *
     * @return the result of the calculation
     * @throws NullPointerException when anything is null, explain what other fields could cause an exception
     */
    public BigDecimal computeSpringRateBoltWasher() {
            Validate.notNull(this.anything, "Anything must not be null");
            //Validate.notNull(somethingElse, "Something else must not be null");
            BigDecimal term1 = this.anything.multiply(BigDecimal.TEN);
            //Do more things with term1 and return a result
            return term1;
    }


    public static void main(String[] args){

            Any any = new Any();
            any.setAnything(new BigDecimal(10));
            BigDecimal result = any.computeSpringRateBoltWasher();
            System.out.println(result);


            any.setAnything(null);
            result = any.computeSpringRateBoltWasher();
            System.out.println(result);

    }
 }

这将产生以下输出(您决定捕获运行时异常)

Exception in thread "main" java.lang.NullPointerException: Anything must not be null
    at org.apache.commons.lang3.Validate.notNull(Validate.java:222)
    at Any.computeSpringRateBoltWasher(Any.java:20)
    at Any.main(Any.java:36)

答案 1 :(得分:1)

如果您使用的是java 7或8,则可以使用Objects.requireNonNull()方法检查空值:

private BigDecimal computeSpringRateBoltWasher() {
    // Perform non-null validations
    // These will throw NullPointerException in case the argument is null
    Objects.requireNonNull(
        boltWasher.getMaterial(), 
        "Material cannot be null");
    Objects.requireNonNull(
        boltWasher.getMaterial().getElastic_modulus(), 
        "Elastic modulus cannot be null");

    BigDecimal term1 = 
        boltWasher.getMaterial().getElastic_modulus().multiply(BigDecimal.TEN);

    // other equations 

    return results;
}

根据您的操作的合同,当参数为null时,您不应返回null,因为在这种情况下您将隐藏错误。如果它对材料或弹性模量无效null,则使用NullPointerException抛出Objects.requireNonNull()

另一方面,如果它对材料或弹性模量有效null,那么你应该仔细处理这个案例。为此,您可以使用多个if语句或一些验证库。

答案 2 :(得分:0)

使用Java 8 Optional,可以以更优雅和可读的方式完成嵌套null检查:

Optional.ofNullable(boltWasher)
    .map(bolt -> bolt.getMaterial())
    .map(mat -> mat.getElastic_modulus)
    .orElse(null)