在 Java 中的 if 条件的同一行中添加 Null 检查并访问 Integer 值是否有效

Is it valid to add a Null check and access the Integer value in the same line of if condition in Java

class Person{
    Integer height;
    integer weight;
}

这样检查有效吗?

Person p = new Person();
if (p.height !=null && p.height >= 1 && p.weight >=1 ){}

是的,这是有效的,因为 Integer 是代表 int 的 class。

这就是为什么Integer可以容纳空值的原因。 p.heightp.weight 的比较也是有效的。

没问题,但请注意,如果 p.weight 为空,这仍会因 NullPointerException 而崩溃。如果您想要干净的代码,请考虑这个问题:

height is null 究竟是什么意思?是否表示:

  • 它在语义上等同于 0。(那么,为什么要有它?使您的字段 int,并正确设置它们)。
  • 未知。
  • 未设置;这是一个不愿公开身高的人

特别是,假设您正在检查 >= 1,显然您可以有一个空高度,但也可以有一个负高度。这两者之间的语义区别是什么?如果没有区别,为什么要允许一系列不同的内部值,但都归结为代表相同的状态?每次与这些变量交互时,您都在注册一系列检查,并进行组合爆炸来测试所有这些。不要这样做 - 创建一个值来表示 'invalid' 或 'unknown' 或 'intentionally omitted' 或您需要传达的任何内容。

通常 如果您 [A] 尽早消除无效状态,它会产生更好的代码,这特别意味着您不需要检查无效状态(此处, 0 和负数似乎是无效的)每次使用这些变量时,[B] 使用标记值而不是 null 来指示唯一状态,例如 'unset' 或 'intentionally not shared'.

换句话说:

  • 将身高和体重保密
  • 如果尝试设置 0 或负身高或体重,他们的设置员将拒绝设置(并抛出 IllegalArgumentException)。
  • 字段的类型是int
  • 存在各种替代状态的常量。
public class Person {
    private static final int UNKNOWN = -1;
    private static final int INTENTIONALLY_OMITTED = -2;
    private int height, weight;

    public Person() {
      this.height = UNKNOWN;
      this.weight = UNKNOWN;
    }

    public void setHeight(int height) {
      if (height < 1) throw new IllegalArgumentException("Non-positive height");
      this.height = height;
    }

    public void setHeightOmitted() {
      this.height = INTENTIONALLY_OMITTED;
    }
}

等等。现在您可以编写本质上可读的代码; null 是模糊的(你必须记录它的意思。它是指未设置、无效还是故意省略?什么?),if (height == INTENTIONALLY_OMITTED) 记录本身,这是一件好事。

是的,因为在 && 操作的情况下,如果第一个条件为真,则将检查第二个条件。如果 p.height 为空,则第一个条件为假,因此不会检查其他条件。

您还必须为 p.width 添加空值检查。