[英]Java program compiles fine, yet returning nullPointerException on run?
I've posted my program for review on code review (stackexchange). 我已经将我的程序发布到代码审查(stackexchange)上进行审查。 Everything worked fine, After I came home I was told to use a IDE.
一切正常,回到家后,我被告知要使用IDE。
I opened my source with Eclipse IDE, and then I started getting (both on the IDE, or without) this error upon run: 我使用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)
Why is it doing that? 为什么这样做呢? My mate has reviewed my code, and could not find anything wrong with it?.
我的队友已经检查了我的代码,找不到任何错误吗?。
I am very new to java, tried at attempting going deeper in OO. 我对Java非常陌生,尝试过更深入的OO。
My code is located at code review thread (3 classes): 我的代码位于代码审查线程(3个类)中:
https://codereview.stackexchange.com/questions/28197/improving-my-java-object-oriented-review https://codereview.stackexchange.com/questions/28197/improving-my-java-object-iented-review
What is wrong with it? 怎么了 Why is it giving me that exception?
为什么给我那个例外?
Line 68: return r.nextInt(x);
第68行:
return r.nextInt(x);
public int rand(int x) {
return r.nextInt(x);
}
That's how I create r object: 这就是我创建r对象的方式:
/**
* Creating new Random object.
**/
private Random r = new Random();
Mains.java: Mains.java:
import games.GameHandler; 导入游戏.GameHandler; import java.util.Scanner;
导入java.util.Scanner; import java.io.*;
导入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: GameHandler.java:
package games; 包装游戏; import java.io.*;
导入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: Spin.java:
package games; 包装游戏; import java.util.Random;
导入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);
}
}
rand
is invoked before the Random
instance r
is initialised. 在初始化
Random
实例r
之前调用rand
。 Switch the order or these 2 statements 切换顺序或这2条语句
private int auth = this.rand(1000) / 5;
private Random r = new Random();
should be 应该
private Random r = new Random();
private int auth = this.rand(1000) / 5;
Make the assignment of r the first thing in your Spinwheel class definition, ie put it before it is used in this.rand(1000): 使r的赋值成为您的Spinwheel类定义中的第一件事,即,将其放在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;
r
is null, so you can't call any instance method on r
. r
为null,因此您不能在r
上调用任何实例方法。 Make sure you intialize r
before using it. 使用前请确保将
r
初始化。
More specifically, in this line: 更具体地说,在这一行:
private int auth = this.rand(1000) / 5;
you're calling the rand()
method before r has been initialized (it's initialized right after). 您正在r初始化之前(在之后立即初始化
rand()
调用rand()
方法。
This is the line causing the NullPointerException
: 这是导致
NullPointerException
的行:
private int auth = this.rand(1000) / 5;
Since this line comes before the initialization for r
, you are invoking rand
before r
was initialized. 由于此行位于
r
的初始化之前 ,因此您要在 r
初始化之前调用rand
。 In that case r
is null
in rand
and that's your exception. 在这种情况下,
r
在rand
为null
,这是您的例外。
This is obvious from your stack trace: 从堆栈跟踪中可以明显看出:
at games.Spin.rand(Spin.java:68)
at games.Spin.<init>(Spin.java:10)
Note that the exception is happening in the initializer . 请注意, 初始化程序中发生了异常。 From there, it's easy to back out what is going on.
从那里,很容易退回正在发生的事情。
You need to initialize r
first, that is, move the initialization line for r
before the initialization line for auth
. 您需要初始化
r
第一个,也就是移动起始线为r
的起始线之前auth
。 Thus: 从而:
private Random r = new Random();
private int auth = this.rand(1000) / 5;
This is because r
is being used before it is instantiated within statement private int auth = this.rand(1000) / 5;
这是因为在语句
private int auth = this.rand(1000) / 5;
r
实例化之前已在使用它private int auth = this.rand(1000) / 5;
. 。 So , JVM is seeing
r
as null
, which is leading to NPE
. 因此,JVM将
r
视为null
,这导致了NPE
。 To get rid of this problem within Spin
class declare the fields as follows: 要摆脱
Spin
类中的此问题,请声明字段,如下所示:
private Random r = new Random();
private int auth = this.rand(1000) / 5;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.