Исключение нулевого указателя - PullRequest
0 голосов
/ 19 июня 2010

После компиляции моего приложения в 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 не оставляет ошибок, и выполнение в порядке.

После проб и ошибок комментирования я пришел к этим анонимным вызовам Актера, который вызывает проблему. Вот функция кода, которая при закомментировании не выдает исключение. Я не могу найти что-то не так с этим.

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

Я отследил эту ошибку до BufferedImage в моем Entity классе.

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)

Ответы [ 3 ]

4 голосов
/ 19 июня 2010
Entity.<init>(Entity.java:24)

Это говорит о том, что исключение выдается в строке 24 "Entity.java". Вы не говорите нам, что это за линия (тск, тск, тск !!) ... но я ожидаю, что именно эта:

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

и что это происходит, потому что loadImage возвращает null.

Другая проблема (но не причина NPE) состоит в том, что в следующей строке используются this.x и this.y до их инициализации. На самом деле, конструктор их вообще не инициализирует !!

Еще одна проблема заключается в том, что ваш метод loadImage явно закодирован, чтобы перехватывать и игнорировать исключения и возвращать null. Таким образом, в принципе, если чтение изображения не удается по какой-либо причине, вы никогда не узнаете об этом. Это вызывает значительное сомнение в вашем утверждении, что изображение успешно загружается. И даже если это не является причиной вашей проблемы, исключать подобные исключения - это крайне плохая практика .

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

РЕДАКТИРОВАТЬ

Проблема теперь в этой строке:

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

и проблема в том, что getClass().getResource(filename) возвращает null и передает его в ImageIO.read, который в результате выбрасывает NPE. Javadoc для Class.getResource(String) говорит, что метод возвращает null, если ресурс не может быть найден.

ЭТО это ваша проблема. Если вы не верите этому диагнозу, добавьте несколько следов, чтобы увидеть, что на самом деле возвращает getClass().getResource(filename).

1 голос
/ 19 июня 2010

Передается ли fileName в loadImage относительный путь? Если это так, он может успешно загрузить изображение из среды IDE, но не снаружи. Это позволило бы правильно загрузить файл в среде IDE, но может привести к исключению нулевого указателя из других сред. Если это так, то использование абсолютного пути может решить проблему.

0 голосов
/ 19 июня 2010

Если вы используете getResource(), как вы делаете в строке, где сейчас происходит ошибка:

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

, тогда Java будет искать файл для загрузки в classpath.Что содержит filename?Это в правильном месте, чтобы его можно было найти относительно пути к классам?

Кроме того, перехват и исключение исключений, как вы делаете в вашем методе 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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...