Java程序编译好,但在运行时返回nullPointerException?

时间:2013-07-06 21:30:00

标签: java

我已发布我的程序以供审查代码审查(stackexchange)。 一切都很好,我回家后被告知使用IDE。

我使用Eclipse IDE打开了我的源代码,然后我开始在运行时获取(无论是在IDE上还是没有)这个错误:

Exception in thread "main" java.lang.NullPointerException
        at games.Spin.rand(Spin.java:68)
        at games.Spin.<init>(Spin.java:10)
        at games.GameHandler.<init>(GameHandler.java:8)
        at Mains.startGame(Mains.java:16)
        at Mains.main(Mains.java:9)

为什么这样做?我的伙伴已经查看了我的代码,但发现它没有任何问题?。

我是java的新手,尝试过深入OO。

我的代码位于代码审查线程(3个类):

https://codereview.stackexchange.com/questions/28197/improving-my-java-object-oriented-review

它出了什么问题?为什么它给我这个例外?

第68行:return r.nextInt(x);

    public int rand(int x) {
        return r.nextInt(x);
    }

这就是我创建r对象的方式:

    /**
    * Creating new Random object.
    **/

    private Random r = new Random();

Mains.java:

导入games.GameHandler; import java.util.Scanner; import java.io。*;

public class Mains {

    public static void main (String[] args) {
        //Start the game
        startGame();

    }

    private static void startGame() {

        //Declares
        GameHandler handler = new GameHandler();
        Scanner console = new Scanner(System.in);   
        boolean game = true;
        String input = "";  

        //Print program welcome text
        handler.printStart();

        //While in game...
        while (game) {
            //Getting input ready for new commands from the player
            input = console.nextLine();

            //Checking if input was set.
            if (input != null) {
                //Selecting the game you want to play.
                handler.selectGame(input);

                //If game was selected.. then.. let's start playing.
                while (handler.inGame) {
                    //Use will say something.
                    input = console.nextLine();

                    //If it was "exit", it will go back and select another game.
                    if (input.equals("exit")) {
                        handler.exitGame();
                    } else {
                        //Play again.
                        handler.continueGame(input);
                    }
                }
            }
        }
    }
}

GameHandler.java:

打包游戏; import java.io。*;

public class GameHandler {

    private String[] games = {"Spin", "Tof"};
    private String[] navigation = {"Back", "Start"};
    private Spin spin = new Spin();
    private boolean spinGame = false;
    private boolean tofGame = false;
    public boolean inGame = false;

    /**
    * Method printStart
    *
    * Will welcome the player to the program.
    */
    public void printStart() {

        this.print(0, "Welcome to the program!");
        this.print(0, "Please select a game: " + this.availableGames());

    }

    /**
    * Method available games
    *
    * This will print all the games that are located in the games array in one row.
    **/

    private String availableGames() {
        String names = "";
        for (int i = 0; i < games.length; i++) {
            names = (names + games[i]);
            if (i < games.length -1) {
                names = (names + ", ");
            }
        }

        return names;
    }

    /**
    * Method selectGame
    *
    * This will select the given game.
    * @param command The entered command.
    **/

    public void selectGame(String command) {
        if (this.inArray(command))
        {
            if (command.equalsIgnoreCase("spin")) {
                this.startGame("spin");
            } else if (command.equalsIgnoreCase("tof")) {
                this.startGame("tof");
            }
        } else {
            this.print(0, "Could not find game!");
        }
    }

    /**
    * Method inArray
    *
    * This will check if the entered game name is exisiting in the games array.
    * If yes, will return a boolean true, else false.
    *
    * @param value The entered game name.
    * @return boolean true/false.
    **/

    private boolean inArray(String value) {
        int returning = 0;
        for (String s : games) {
            if (value.equalsIgnoreCase(s)) {
                returning = 1;
            }
        }
        if (returning == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
    * Method startGame
    *
    * Will start the game, and print instructions.
    * will set the game boolean to true.
    **/

    private void startGame(String game) {
        switch (game) {
            case "spin":
                this.print(0, "Welcome to spin game!");
                this.print(0, "Please click on any key to spin!");
                spinGame = true;
            break;
            case "tof":
            break;
        }

        inGame = true;
    }

    /**
    * Method continueGame
    *
    * Will continue the game, either spin again, or print new question or even answer.
    * @param command The entered command.
    **/
    public void continueGame(String command) {
        while (inGame) {
            if (spinGame) {
                this.spinWheel();
                // Break out of the loop.
                break;
            }
        }
    }

    /**
    * Method exitGame
    *
    * Exit the game..
    **/

    public void exitGame() {
        spinGame = false;
        tofGame = false;
        this.printStart();
    }

    /**
    * Method spinWheel
    *
    * This will spin the wheel.
    **/

    private void spinWheel() {
        this.print(0, spin.spinWheel());
    }

    /**
    * Method print
    *
    * Prints text using System.out
    * @param type printing type (Println/print).
    * @param message The message
    **/

    private void print(int type, String message) {
        switch (type) {
            case 0:
                System.out.println(message);
            break;
            case 1:
                System.out.print(message);
            break;              
        }
    }
}

Spin.java:

打包游戏; import java.util.Random;

public class Spin {

    /**
    * The base auth we are going to work with..
    **/

    private int auth = this.rand(1000) / 5; 

    /**
    * Creating new Random object.
    **/

    private Random r = new Random();

    /**
    * Method spinWheel
    *
    * Spins the damn wheel..
    * @return spinned value + if you won or not.
    **/

    public String spinWheel() {
        return this.spinWheel(this.rand(100));
    }

    /**
    * spinWheel
    *
    * Returning results.
    **/

    private String spinWheel(int number) {

        int result = this.Calculate(this.rand(number));

        if (result < 101) {
            return "You have won the game!" + result;
        } else {
            return "You've lost the game!" + result;
        }
    }

    /**
    * Method calculate
    *
    * Calculates the spin.
    * @return the spinned number.
    **/


    private int Calculate(int Number) {

        int var = this.rand(101);

        int holder = (var * Number) / 2;

        return holder + this.auth;
    }

    /**
    * Shortcut for nextInt of Random
    **/

    public int rand(int x) {
        return r.nextInt(x);
    }

}

5 个答案:

答案 0 :(得分:4)

在初始化rand实例Random之前调用

r。切换订单或这两个陈述

private int auth = this.rand(1000) / 5; 
private Random r = new Random();

应该是

private Random r = new Random();
private int auth = this.rand(1000) / 5; 

答案 1 :(得分:2)

在你的Spinwheel类定义中首先分配r,即在它之前将它放在this.rand(1000)中:

public class Spin {
  /**
   * Creating new Random object.
   **/
  private Random r = new Random();

  /**
   * The base auth we are going to work with..
   **/
  private int auth = this.rand(1000) / 5; 

答案 2 :(得分:1)

r为空,因此您无法在r上调用任何实例方法。确保在使用之前初始化r

更具体地说,在这一行:

private int auth = this.rand(1000) / 5; 

您在初始化r之前调用rand()方法(之后立即初始化)。

答案 3 :(得分:1)

这是导致NullPointerException

的行
private int auth = this.rand(1000) / 5; 

由于在<{1}}的初始化之前,所以在 r初始化之前,您正在调用rand 。在这种情况下r r位于null,这是您的例外。

从堆栈跟踪中可以看出这一点:

rand

请注意,初始化程序中发生了异常。从那里,很容易退出正在发生的事情。

首先需要初始化at games.Spin.rand(Spin.java:68) at games.Spin.<init>(Spin.java:10) ,即在r的初始化行之前移动r的初始化行。因此:

auth

答案 4 :(得分:1)

这是因为r在语句private int auth = this.rand(1000) / 5;中实例化之前正在使用。因此,JVM将r视为null,这导致NPE。要在Spin类中解决此问题,请按以下方式声明字段:

    private Random r = new Random();
    private int auth = this.rand(1000) / 5;