【问题标题】:Is there a way that i can make my object never null?有没有办法让我的对象永远不会为空?
【发布时间】:2022-01-02 22:56:12
【问题描述】:

我接到了一项任务,但我不知道如何让它发挥作用。所有的测试用例都必须通过。

Assertions.assertDoesNotThrow(() -> p3.equals(null));
Assertions.assertFalse(p3.equals(null), "equals to null should return false");
  

我发现了第一个,欺骗我的是 Assertions.assertfalse(p3.equals(null))。 我从 Point 这样创建了对象 p3:

Point p3 = new Point(x+1, y-1);

在我的 Point 类中,我有一个 equals 方法,我将其重写为:

@Override
public boolean equals(Object obj) {
    Point p = (Point) obj;
    try {
        if (x != p.x) {
            return false;
        }

        if (y != p.y) {
            return false;
        }
    } catch (NullPointerException e) {
        System.err.println("null");
    }
    return true;
}

我用它来通过其他未提及的测试。

public Point(int x, int y) {
    this.x = x;
    this.y = y;
}

public int x() {
    return x;
}

public int y() {
    return y;
}

其中 x 和 y 是 0-30 之间的随机整数。

当我运行测试时,它总是返回等于 null 的 p3,这让我很困惑。我知道这与检查通过的对象是否属于相同类型(点)和向下转换有关,但我不确定。

【问题讨论】:

  • 一个对象实例化表达式 (new ...) 永远不会返回 null 如果它没有任何异常地完成。我担心,我不明白这个问题。
  • 附带说明,检查p3.equals(null) 没有任何意义。如果变量为空,则表达式抛出 NPE。如果它不为空,那么它总是评估为false
  • @Seelenvirtuose 也许是为第二部分编写测试。所以这只是在Point.equals(Object other)方法中检查if(!(other instanceof Point)) return false;的问题。
  • 不要在 equals 方法中捕获 NPE!
  • 试试return obj instanceof Point p && p.x == x && p.y == y;

标签: java object nullpointerexception null downcast


【解决方案1】:

如果您查看您正在实现的 equals 方法的签名,您会发现它采用 Object 类型的参数。这意味着传入的东西可以是任何引用类型。它可以为空。目前,您的 equals 方法盲目地将它得到的任何东西都投射到一个点,所以如果它得到一个点以外的任何东西,那么就会抛出一个异常。之后,如果传入的东西为空,引用实例成员(如 p.x)将导致 NullPointerException。

至少需要为 equals 方法编写四个测试:

  1. 传入另一个具有相同x和y值的Point,

  2. 传入具有不同 x 和 y 值的 Point。

  3. 传入一些完全不同类型的对象,比如字符串或整数。

  4. 传入null。

这些需要采用不同的测试方法,以便它们可以彼此独立地失败。将它们塞进同一个测试意味着当一个断言失败时,它之后的断言不会运行;修复测试变成了一个打地鼠的情况,你修复了一个问题,但现在又出现了另一个问题。

你可以使用 instanceof 来检查你得到的是正确的类型并且是非空的。由于您当前的代码捕获了 NPE,因此它可以让执行从 catch 块继续到带有 return true; 的行,这不是您想要的。

所以用类似的东西开始你的equals方法

if (!(object instanceof Point)) {
    return false;
}

在你施法之前。一旦你知道对象是一个非空点,那么你可以继续

Point p = (Point)object;
return x == p.x && y == p.y;

由于 && 短路,这不会比发布的代码做更多的工作,如果第一次检查的结果为 false,它们都会停止检查。

【讨论】:

    猜你喜欢
    • 2016-06-06
    • 2021-06-22
    • 2014-08-11
    • 2020-03-19
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    相关资源
    最近更新 更多