简体   繁体   English

Java:简单但不寻常的NullPointerException

[英]Java: simple but unusual NullPointerException

I'm stuck on something that is usually really simple. 我坚持通常非常简单的事情。 I'm getting a NullPointerException when calling this simple class's constructor: 调用这个简单类的构造函数时,我得到一个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;
        }
    }

It gets called this way: 它以这种方式调用:

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

No matter what I try, I always get a NullPointerException trying to initialize that class. 无论我尝试什么,我总是会尝试初始化该类的NullPointerException。

EDIT: 编辑:

Tristan's suggestions along with changing the nested for loops to the code below fixed it 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);
            }
        }

I think you are accidentally redeclaring shape as an uninitialized field. 我认为你不小心将形状重新定义为未初始化的领域。 The shape you are calling setRect on has not been initialized the way you think it has. 您调用setRect on的形状尚未按您认为的方式初始化。

If you have a shape in the parent class that you are trying to access, simply set its modifier to protected and remove the private shape declaration in the class you posted. 如果您尝试访问的父类中有一个形状,只需将其修饰符设置为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);
}

However looking through this constructor, it seems rather off. 然而,通过这个构造函数,它似乎相当偏离。 If it is the case that the parent class has a shape itself, why do you need to set the rectangle any differently than the way you set it in the parent class? 如果父类本身具有形状,为什么需要设置矩形的方式与在父类中设置它的方式不同?

For example, this code appears to be logically equivalent. 例如,此代码似乎在逻辑上是等效的。

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

As mentioned by Tristan, the problem with the initial brick constructor is that shape has been declared but not instantiated. 正如Tristan所提到的,初始砖构造函数的问题是已声明形状但未实例化。

That said, it is simple to instantiate shape: 也就是说,实例化形状很简单:

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

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

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