Java:简单但不寻常的NullPointerException

时间:2014-03-15 00:57:24

标签: java nullpointerexception

我坚持通常非常简单的事情。我在调用这个简单类的构造函数时遇到NullPointerException:

import java.awt.geom.*;

public class Brick extends ColorShape {
        private int xPos = 0;
        private int yPos = 0;
        private int width = 0;
        private int height = 0;
        private Rectangle2D.Double shape;

        // constructor
        public Brick(int x, int y, int w, int h) {
            super(new Rectangle2D.Double(x, y, w, h));

            //set brick x, y, width, and height
            xPos = x;
            yPos = y;
            width = w;
            height = h;

            // update shape
            shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
        }

        public int getX() {
            return xPos;
        }

        public Rectangle2D.Double getShape() {
            return shape;
        }
    }

以这种方式调用它:

for (int i = 0; i < numCols; i++) {
            for (int j = 0; j < numRows; j++) {

                // initialize bricks[i][j]
                bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
                bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
                //bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
                //bricks[i][j] = new Brick(0, 0, 0, 0);
            }
        }

无论我尝试什么,我总是会尝试初始化该类的NullPointerException。

编辑:

Tristan的建议以及将嵌套for循环更改为下面的代码修复它

// create new bricks and store them in bricks array
        for (int i = 0; i < numCols; i++) {
            for (int j = 0; j < numRows; j++) {


                // initialize bricks[i][j]
                //bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
                //bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
                bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
                //bricks[i][j] = new Brick(0, 0, 0, 0);
            }
        }

2 个答案:

答案 0 :(得分:2)

我认为你不小心将形状重新定义为未初始化的字段。您正在调用setRect的形状尚未按您认为的方式进行初始化。

如果您尝试访问的父类中有一个形状,只需将其修饰符设置为protected并删除您发布的类中的私有形状声明。

/* REMOVE THIS */
private Rectangle2D.Double shape; // uninitialized!

// constructor
public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));

    //set brick x, y, width, and height
    xPos = x;
    yPos = y;
    width = w;
    height = h;
    // update shape
    // This now references a protected instance variable inherited from the parent.
    shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
}

然而,通过这个构造函数,它似乎相当偏离。如果父类本身具有形状,为什么需要设置矩形的方式与在父类中设置方式的方式不同?

例如,此代码 出现 在逻辑上等效。

// Call the parents constructor to set the shape of this brick..
public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));
}

答案 1 :(得分:0)

如Tristan所述,初始砖构造函数的问题是已声明形状但未实例化。

也就是说,实例化形状很简单:

public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));

    //set brick x, y, width, and height
    xPos = x;
    yPos = y;
    width = w;
    height = h;
    // update shape
    // This now references a protected instance variable inherited from the parent.
    shape = (Rectangle2D.Double)super.shape;
    shape.setRect(xPos, yPos, width, height);
}