簡體   English   中英

空指針異常

[英]NullPointerException

在NetBeans中編譯我的應用程序並在Netbeans中運行該應用程序后,它就可以正常工作。

所有圖像加載良好。

嘗試雙擊執行該應用程序不會導致任何事情。

嘗試從命令行運行會出現以下錯誤:

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)

在Netbeans外部進行編譯不會留下任何錯誤,並且可以正常執行。

經過反復試驗和評論錯誤,我來到了匿名調用Actor的電話,這引起了問題。 這是代碼的功能,注釋掉后不會拋出異常。 我似乎找不到任何問題。

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

我進一步在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;
    }
}

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

收到此新錯誤:

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)

這告訴您在“ Entity.java”的第24行引發了異常。 您不告訴我們哪條線(tsk,tsk,tsk !!)...但是我希望這是這條線:

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

這是因為loadImage返回null

另一個問題(盡管不是NPE的原因)是,下一行在初始化之前使用this.xthis.y 實際上,構造函數根本不會初始化它們!

另一個問題是您的loadImage方法被顯式編碼以捕獲和忽略異常,並返回null 因此,基本上,如果圖像讀取由於任何原因而失敗,您將永遠不會知道它。 這使您對是否已成功加載映像的斷言產生了極大的懷疑 即使這不是造成您問題的原因,擠壓這樣的異常也是非常糟糕的做法

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

編輯

現在問題出在這一行:

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

問題是getClass().getResource(filename)返回null並將其傳遞給ImageIO.read ,從而拋出NPE。 Class.getResource(String)的javadoc說,如果找不到資源,則該方法返回null

是你的問題。 如果您不相信這種診斷,請添加一些跟蹤記錄以查看getClass().getResource(filename)實際返回的內容。

傳遞給loadImage的fileName是相對路徑嗎? 如果是這樣,它可以從IDE內部成功加載圖像,但不能從外部加載圖像。 這將使文件在IDE中正確加載,但可能導致其他環境導致空指針異常。 如果是這種情況,使用絕對路徑可以解決此問題。

如果使用getResource() ,就像在發生錯誤的那一行一樣:

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

然后Java將尋找要在類路徑上加載的文件。 filename包含什么? 它在正確的位置以便可以相對於類路徑找到它嗎?

另外,捕獲和忽略異常,就像在Entity.loadImage()方法中所做的Entity.loadImage()

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

是您作為Java開發人員可能犯下的最嚴重的罪行之一。 不要那樣做 至少記錄該異常,以其他方式處理該異常,或者聲明該異常發生的方法將其引發。 例如:

// 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