使用静态属性的Java代码的奇怪行为

r3s*_*0r3 0 java static

我真的没什么要问的.哎呀我甚至不知道问题应该说什么.基本上,这个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--;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我删除该行

Application app = new Application(); 
Run Code Online (Sandbox Code Playgroud)

从第一个类中的main方法开始,它抛出一个NullPointerException

tiles[rowIndex][columnIndex] = new String("M"); 
Run Code Online (Sandbox Code Playgroud)

有什么理由吗?

kos*_*osa 10

Application app = new Application();
Run Code Online (Sandbox Code Playgroud)

如果你没有实例化Application,tiles将指向null.对空引用的操作导致NullPointerException.

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

public Application() {
        tiles = new String[9][9];
    }
Run Code Online (Sandbox Code Playgroud)

构造函数将仅在Object creation(new Application())上执行

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

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

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


Roh*_*ain 5

您注意到您已在构造函数中实例化了数组?

static String[][] tiles;

public Application() {
    tiles = new String[9][9];  <--- Here
}
Run Code Online (Sandbox Code Playgroud)

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

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

static {
    tiles = new String[9][9];
}
Run Code Online (Sandbox Code Playgroud)

要么

static String[][] tiles = new String[9][9];
Run Code Online (Sandbox Code Playgroud)

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