-1

我已经在代码审查 (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-orientated-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();

电源.java:

导入游戏.GameHandler;导入 java.util.Scanner;导入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:

打包游戏;导入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;              
        }
    }
}

旋转.java:

打包游戏;导入 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);
    }

}
4

5 回答 5

4

randRandom在实例r初始化之前调用。切换顺序或这2个语句

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

应该

private Random r = new Random();
private int auth = this.rand(1000) / 5; 
于 2013-07-06T21:34:14.923 回答
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; 
于 2013-07-06T21:33:27.513 回答
1

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

更具体地说,在这一行中:

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

rand()在 r 被初始化之前调用该方法(它在之后被初始化)。

于 2013-07-06T21:31:41.353 回答
1

这是导致NullPointerException

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

由于此行在初始化之前出现,因此您在初始化之前r调用。在那种情况下,那是你的例外。rand rrnullrand

从您的堆栈跟踪中可以明显看出这一点:

at games.Spin.rand(Spin.java:68)
at games.Spin.<init>(Spin.java:10)

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

需要先初始化r,即将初始化行 for 移到初始化行 forr之前auth。因此:

private Random r = new Random();
private int auth = this.rand(1000) / 5; 
于 2013-07-06T21:34:06.430 回答
1

这是因为r在 statement 实例化之前正在使用它private int auth = this.rand(1000) / 5;。所以,JVM 是r看成null,这就是导致NPE。要在Spin类中消除此问题,请按如下方式声明字段:

    private Random r = new Random();
    private int auth = this.rand(1000) / 5; 
于 2013-07-06T21:34:54.827 回答