0

我真的没有太多要问的。哎呀,我什至不知道这个问题应该说什么。基本上,这段 Java 代码运行良好,没有任何编译错误。

public class Application {
    static String[][] tiles;

    public Application() {
        tiles = new String[9][9];
    }

    public static void main(String[] args) {

        Application app = new Application();
        Grid mines = new Grid();
        mines.fillTiles(tiles, 9, 9, 10);
    }
}

class Grid {
    Random rand;

    public void fillTiles(String[][] tiles, int rowSize, int colSize,
            int numMines) {
        rand = new Random();
        int rowIndex;
        int columnIndex;
        while (numMines > 0) {
            rowIndex = rand.nextInt(rowSize);
            columnIndex = rand.nextInt(colSize);
            tiles[rowIndex][columnIndex] = "M";
            numMines--;
        }
    }
}

但是,当我删除线

Application app = new Application(); 

从第一类的主要方法,它在抛出一个 NullPointerException

tiles[rowIndex][columnIndex] = new String("M"); 

有什么理由吗?

4

5 回答 5

10
Application app = new Application();

如果您不实例化Application,tiles将指向null. 对空引用的操作会导致NullPointerException.

您的 Array 初始化逻辑在构造函数中。

public Application() {
        tiles = new String[9][9];
    }

构造函数将仅在创建对象时执行 ( new Application())

如果你不想做Application app = new Application();

只是改变 static String[][] tiles=new String[9][9];

定义static数组变量并不意味着实例化将在加载时发生。这只是意味着该变量是类变量。

于 2012-11-07T18:19:57.920 回答
5

你注意到你已经在你的构造函数中实例化了你的数组吗?

static String[][] tiles;

public Application() {
    tiles = new String[9][9];  <--- Here
}

因此,如果您不实例化您的Applicationusing new Application(),您的数组将不会被初始化,并且您的引用将指向 null。

此外,在构造函数中初始化静态变量也不是一个好主意。static initializer block理想情况下,您应该在 a或声明本身的位置初始化您的静态数组:-

static {
    tiles = new String[9][9];
}

或者

static String[][] tiles = new String[9][9];

如果您在构造函数中初始化数组,则每次创建一个实例时,它都会为每个实例重新初始化。因为static变量对所有实例都是通用的。因此,您对static变量所做的更改将反映在您的所有实例中。

于 2012-11-07T18:21:21.313 回答
2

我想我可能知道原因:

public class Application {
    static String[][] tiles;

    public Application() {
        tiles = new String[9][9];
    }

    public static void main(String[] args) {

        Application app = new Application();
        Grid mines = new Grid();
        mines.fillTiles(tiles, 9, 9, 10);
    }
}

在此,您有一个静态二维数组,其中包含称为图块的字符串。但是,您只能在 Application 的构造函数中对其进行初始化。因此,当调用“mines.fillTiles(tiles”时,tiles 仍然为 null 并且

tiles[rowIndex][columnIndex] = new String("M"); 

将抛出 NullPointerException。

于 2012-11-07T18:22:09.430 回答
2

因为您正在构造函数中进行初始化tiles = new String[9][9];。仅当您使用new将对象实例创建为new Application().

如果您不想使用构造函数,请将带有初始化的静态变量声明为:

    static String[][] tiles = new String[9][9];

如果没有构造函数调用,那应该可以正常工作。

于 2012-11-07T18:21:22.837 回答
0

您正在实例的构造函数中初始化数组。如果您在第一个实例之后创建另一个实例,它将重新初始化静态成员。

于 2012-11-07T18:21:07.963 回答