繁体   English   中英

具有静态属性的Java代码的奇怪行为

[英]Strange behavior of Java code with static attribute

我真的没什么要问的。 哎呀,我什至不知道该说什么。 基本上,此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"); 

有什么原因吗?

Application app = new Application();

如果不实例化Applicationtiles将指向null 对空引用进行操作会导致NullPointerException

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

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

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

如果您不想执行Application app = new Application();

只需更改static String[][] tiles=new String[9][9];

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

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

static String[][] tiles;

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

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

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

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

要么

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

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

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

如果您不想使用构造函数,请通过以下方式将静态变量声明为:

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

不用构造函数调用就可以正常工作。

我想我可能知道原因:

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);
    }
}

在这种情况下,您有一个静态2d数组,其中包含称为tile的字符串。 但是,您只能在Application的构造函数中对其进行初始化。 因此,当调用“ mines.fillTiles(tiles)”时,tile仍为null,并且

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

将抛出NullPointerException。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM