简体   繁体   English

空指针异常

[英]NullPointerException

After compiling my application in Netbeans and running the application in Netbeans it works just fine. 在NetBeans中编译我的应用程序并在Netbeans中运行该应用程序后,它就可以正常工作。

All images load fine. 所有图像加载良好。

Trying to double click execute the application results in nothing happening. 尝试双击执行该应用程序不会导致任何事情。

Trying run from command line gives this error: 尝试从命令行运行会出现以下错误:

Exception in thread "main" java.lang.NullPointerException
     at Entity.<init>(Entity.java:24)
     at Actor.<init>(Actor.java:5)
     at TileEngine.drawMap(TileEngine.java:52)
     at GraphicsCanvas.<init>(GraphicsCanvas.java:32)
     at Main.<init>(Main.java:22)
     at Main.main(Main.java:18)

Compiling outside of Netbeans leaves no errors and execution is fine. 在Netbeans外部进行编译不会留下任何错误,并且可以正常执行。

After trial and error of commenting I've came to these the anonymous call to Actor that is causing the problem. 经过反复试验和评论错误,我来到了匿名调用Actor的电话,这引起了问题。 Here is function of the code that when commented out does not throw the exception. 这是代码的功能,注释掉后不会抛出异常。 I cant seem to find anything wrong with it. 我似乎找不到任何问题。

public class Actor extends Entity
{
    Actor(String filename, int x, int y)
    {
        super(filename, x, y);
    }
}


void drawMap(String imgWalkable, String imgNotWalkable, GraphicsCanvas gp)
    {
        // Since each 1 tile is a tile that can be walked on
        // we need to set the 1 tile to something you can walk on.
        // The tiles that cannot be walked on are the ones that are 0

        for (int x = 0; x < WID; x++)
        {
            for (int y = 0; y < HEI; y++)
            {
                if (GRID[x][y] == 1)
                    gp.add(new Actor(imgWalkable, x * TILE_WID, y * TILE_HEI));
                //else
                    //gp.add(new Actor(imgNotWalkable, x * TILE_WID, y * TILE_HEI));
            }
        }
    }

I have further traced this error to BufferedImage in my Entity class. 我进一步在Entity类中将此错误跟踪到BufferedImage。

public class Entity extends JLabel
{
    Entity(String filename, int x, int y)
    {
        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        bImg = loadImage(filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        ImageIcon icon = new ImageIcon(bImg);
        setIcon(icon);
    }

    public BufferedImage loadImage(String filename) {
        BufferedImage tmp = null;
        try {
            tmp = ImageIO.read(getClass().getResource(filename));
        } catch (Exception e) { }
        return tmp;
    }
}

After removing loadImage function and instead loading the image like this: 删除loadImage函数并改为像这样加载图像后:

Entity(String filename, int x, int y)
    {
        try {
        bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25
        } catch (IOException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        //bImg = loadImage(filename);
        //loadImage(bImg, filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        Icon icon = new ImageIcon(bImg);
        setIcon(icon);
        setVisible(isAlive);
    }

This new error is received: 收到此新错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: input == null!
     at javax.imageio.ImageIO.read(ImageIO.java:1362)
     at Entity.<init>(Entity.java:25)
Entity.<init>(Entity.java:24)

This tells you that the exception is being thrown at line 24 of "Entity.java". 这告诉您在“ Entity.java”的第24行引发了异常。 YOU DON'T TELL US WHICH LINE THAT IS (tsk, tsk, tsk!!) ... but I expect it is this one: 您不告诉我们哪条线(tsk,tsk,tsk !!)...但是我希望这是这条线:

this.setSize(bImg.getWidth(), bImg.getHeight());

and that it is happening because loadImage is returning null . 这是因为loadImage返回null

Another problem (though not the cause of the NPE) is that the following line uses this.x and this.y before they have been initialized. 另一个问题(尽管不是NPE的原因)是,下一行在初始化之前使用this.xthis.y In fact, the constructor doesn't initialize them at all!! 实际上,构造函数根本不会初始化它们!

Yet another problem is that your loadImage method is explicitly coded to catch and ignore exceptions, and return null . 另一个问题是您的loadImage方法被显式编码以捕获和忽略异常,并返回null So basically, if the image read does fail for any reason, you will never know about it. 因此,基本上,如果图像读取由于任何原因而失败,您将永远不会知道它。 This casts considerable doubt on your assertion that the image is being successfully loaded. 这使您对是否已成功加载映像的断言产生了极大的怀疑 And even if this is not the cause of your problem, squashing exceptions like that is extremely bad practice . 即使这不是造成您问题的原因,挤压这样的异常也是非常糟糕的做法

this.setLocation(this.x, this.y);

EDIT 编辑

The problem is now in this line: 现在问题出在这一行:

bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25

and the problem is that getClass().getResource(filename) is returning null and passing it to ImageIO.read which is throwing the NPE as a result. 问题是getClass().getResource(filename)返回null并将其传递给ImageIO.read ,从而抛出NPE。 The javadoc for Class.getResource(String) says that the method returns null if the resource cannot be found. Class.getResource(String)的javadoc说,如果找不到资源,则该方法返回null

THAT is your problem. 是你的问题。 If you don't believe this diagnosis, add some traceprints to see what getClass().getResource(filename) actually returning. 如果您不相信这种诊断,请添加一些跟踪记录以查看getClass().getResource(filename)实际返回的内容。

Is the fileName being passed to loadImage a relative path? 传递给loadImage的fileName是相对路径吗? If so, it could successfully load the image from within the IDE but not from outside it. 如果是这样,它可以从IDE内部成功加载图像,但不能从外部加载图像。 That would let the file load correctly within the IDE but may result in a null pointer exception from other environments. 这将使文件在IDE中正确加载,但可能导致其他环境导致空指针异常。 If that is the case, using an absolute path may fix the issue. 如果是这种情况,使用绝对路径可以解决此问题。

If you use getResource() , like you are doing in the line where the error now happens: 如果使用getResource() ,就像在发生错误的那一行一样:

bImg = ImageIO.read(getClass().getResource(filename));

then Java will look for the file to load on the classpath. 然后Java将寻找要在类路径上加载的文件。 What does filename contain? filename包含什么? Is it in the right place so that it can be found relative to the classpath? 它在正确的位置以便可以相对于类路径找到它吗?

Also, catching and ignoring exceptions, as you're doing in your Entity.loadImage() method: 另外,捕获和忽略异常,就像在Entity.loadImage()方法中所做的Entity.loadImage()

try {
    tmp = ImageIO.read(getClass().getResource(filename));
} catch (Exception e) { }

is one of the worst sins you can commit as a Java developer. 是您作为Java开发人员可能犯下的最严重的罪行之一。 Don't do that; 不要那样做 at least log the exception, handle it some other way, or declare that the method it happens in throws it. 至少记录该异常,以其他方式处理该异常,或者声明该异常发生的方法将其引发。 For example: 例如:

// Declare that the method might throw IOException
public BufferedImage loadImage(String filename) throws IOException {
    // ...

    // No need to try / catch the exception now
    tmp = ImageIO.read(getClass().getResource(filename));
}

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

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