首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UC Berkley CS61B:数据结构(免费在线课程)-项目0: 2048游戏问题-方法给我空指针异常错误

UC Berkley CS61B:数据结构(免费在线课程)-项目0: 2048游戏问题-方法给我空指针异常错误
EN

Stack Overflow用户
提问于 2022-02-04 22:39:36
回答 1查看 976关注 0票数 -2

我很难为项目0: 2048实现下面的方法游戏:

公共静态布尔maxTileExists(B板)

如果板中的任何瓷砖等于获胜的瓷砖值2048,则此方法应返回true。注意,与其将常量2048硬编码到代码中,不如使用MAX_PIECE,它是模型类的一部分。换句话说,您不应该执行if (x == 2048),而应该执行if (x == MAX_PIECE)。留下像2048这样的硬编码数字是一种糟糕的编程实践,有时被称为“魔术数字”。这种神奇数字的危险在于,如果您在代码的一个部分而不是另一个部分中更改它们,您可能会得到意想不到的结果。通过使用像MAX_PIECE这样的变量,您可以确保它们一起被更改。在编写了该方法之后,TestMaxTileExists.java中的测试应该会通过。

下面是我的代码:

代码语言:javascript
复制
 /**
     * Returns true if any tile is equal to the maximum valid value.
     * Maximum valid value is given by MAX_PIECE. Note that
     * given a Tile object t, we get its value with t.value().
     */
    public static boolean maxTileExists(Board b) {
        // TODO: Fill in this function.
        for (int i = 0; i < b.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                if (b.tile(i, j).value() == MAX_PIECE) {
                    return true;
                }
            }
        }
        return false;
    }

--我在测试时一直收到这个错误:

java.lang.NullPointerException:无法调用"game2048.Tile.value()“,因为"game2048.Board.tile(int,int)”的返回值为空

--我需要实现的第一个方法--下面这个方法很好地工作,并通过了所有的测试用例:

公共静态布尔emptySpaceExists(B板)

如果给定板中的任何瓷砖为null,则此方法应返回true。您不应该以任何方式修改该项目的Board.java文件。对于此方法,您将需要使用Board类的平铺( int行)和size()方法。没有其他方法是必要的。注意:我们使用一个特殊的关键字私有来设计Board类,它不允许您直接使用Board的实例变量。例如,如果您尝试访问b.values,这将无法工作。这是件好事!它迫使您学习使用瓷砖方法,该方法将在整个项目的其余部分中使用。尝试打开TestEmptySpace.java文件夹。做测试。你应该看到有6个测试失败了,其中2个通过了。在正确地编写了emptySpaceExists方法之后,TestEmptySpace中的所有8个测试都应该通过。

下面的代码如下:

代码语言:javascript
复制
/**
     * Returns true if at least one space on the Board is empty.
     * Empty spaces are stored as null.
     */
    public static boolean emptySpaceExists(Board b) {
        // TODO: Fill in this function.
        for (int i = 0; i < b.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                if (b.tile(i, j) == null) {
                    return true;
                }
            }
        }
        return false;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-04 23:29:20

首先,当您试图访问尚未初始化的内容时,通常会发生NullPointerException。在您的示例中,这是.value()函数。

在第二个代码块中,您可能会意识到您使用的代码有一个主要区别:这将是代码的"== null“部分,而不是".value() == MAX_PIECE”。

现在,为什么其中一个会抛出一个错误,而另一个却不会呢?

这是因为当您检查某物是否为"null“时,您将看到它是否存在。如果没有,那么您的程序将返回true,如果它确实存在,那么您的程序将返回false。

另一方面,当您在对象上调用.value()时,您已经假定该对象存在。这意味着,例如,如果对象尚未初始化,程序将尝试取消对存储在变量中的指针的引用,但很快就会意识到指针实际上并没有指向任何东西。

要修复这样的错误,只需确保要访问的内容是存在的。

例如:假设我们有Person x

代码语言:javascript
复制
Person x;

在这里,我们可以很快地看到,如果我们尝试这样的东西,我们就会抛出一个错误:

代码语言:javascript
复制
System.out.println(x.name());

当然,这是因为x还不存在。

但是,如果我们想知道Person x是否存在,我们只需这样做:

代码语言:javascript
复制
System.out.println(x == null);

在我们的例子中,这并不是必要的,因为我们可以清楚地看到Person x还没有定义,但是在像您这样的例子中,您正在同时处理许多不同的对象,这样的一行可以真正帮助我们。

这意味着,如果要确保在方法中不抛出NullPointerException,则只需添加一行(或更改一行,这是防止异常以达到学习目标的较少冗长的版本)。

代码语言:javascript
复制
public static boolean maxTileExists(Board b) {
    // TODO: Fill in this function.
    for (int i = 0; i < b.size(); i++) {
        for (int j = 0; j < b.size(); j++) {
            if (b.tile(i, j) == null) continue;
            if (b.tile(i, j).value() == MAX_PIECE) {
                return true;
            }
        }
    }
    return false;
}

通过添加继续for循环的if语句,我们跳过了程序试图取消引用一个似乎不存在的对象的点。

但是,在使用这段代码之前,需要注意的一点是:您的平铺也可能已经存在了,在我看来,这是很有可能的。这将是您的代码中的一个更深层次的问题,您将通过遍历并确保在程序开始时初始化每个块来解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70993632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档