Java 中使用 Runnables 的带有枚举的 nullPointerException
nullPointerException with enum using Runnables in Java
我已经通读了 nullPointerExceptions 的解释,我知道当指向的值具有 null 值时,就好像它在引用一个对象一样,但我无法理解为什么我会得到一个枚举的使用有点像 switch 语句,但当然不是实际使用 switch 语句。正如我提到的,预期的行为应该像一个 switch 语句。也许我缺少对枚举和 NPE 概念的基本理解。我的代码如下。 (此代码适用于 Enigma 密码机)
void displayMenu() {
System.out.println("MAIN MENU");
System.out.println();
Stream.of(menuChoice.values()).map(stream -> stream.ordinal() + ". " + stream.msg).forEach(System.out::println);
System.out.println();
}
public enum menuChoice {
QUIT("Quit the Enigma", EnigmaMachine.instance.quitAction),
ENCRPYT("Encrypt", EnigmaMachine.instance.encryptAction),
DECRYPT("Decrypt", EnigmaMachine.instance.decryptAction);
private String msg;
public Runnable action;
private menuChoice(String message, Runnable r) {
this.msg = message;
this.action = r;
}
}
menuChoice getUserChoice() {
System.out.print("Please enter your choice: ");
int choice = s.nextInt();
return menuChoice.values()[choice];
}
在 QUIT 常量上,我正在使用一个可运行的设置:
final Runnable quitAction = () -> {
EnigmaMachine.instance.running = false;
};
堆栈跟踪是这样的:
Exception in thread "main" java.lang.ExceptionInInitializerError
at enigmamachine.EnigmaMachine.displayMenu(EnigmaMachine.java:24)
at enigmamachine.EnigmaMachine.<init>(EnigmaMachine.java:85)
at enigmamachine.EnigmaMachine.main(EnigmaMachine.java:91)
Caused by: java.lang.NullPointerException
at enigmamachine.EnigmaMachine$menuChoice.<clinit>(EnigmaMachine.java:30)
... 3 more
Java Result: 1
我的构造函数是这样的:
public EnigmaMachine() {
this.running = true;
while (this.running) {
displayMenu();
getUserChoice().action.run();
}
}
对象实例是在我的代码底部的 main 函数之上定义的。
static EnigmaMachine instance;
public static void main(String[] args) {
instance = new EnigmaMachine();
}
我不一定在寻找解决方案,但也许是对我正在处理的事情的更相关的解释。
非常感谢。
您遇到这个问题只是因为 EnigmaMachine.instance
在此处 QUIT("Quit the Enigma", EnigmaMachine.instance.quitAction)
调用时仍然是 null
。你不应该在你的构造函数中调用 displayMenu()
因为它太早了,你应该调用它一个方法来避免这个问题。
例如,您可以向 class 添加一个方法开始,如下所示:
public void start() {
this.running = true;
while (this.running) {
displayMenu();
getUserChoice().action.run();
}
}
然后在main
方法中调用next
instance = new EnigmaMachine();
instance.start();
我已经通读了 nullPointerExceptions 的解释,我知道当指向的值具有 null 值时,就好像它在引用一个对象一样,但我无法理解为什么我会得到一个枚举的使用有点像 switch 语句,但当然不是实际使用 switch 语句。正如我提到的,预期的行为应该像一个 switch 语句。也许我缺少对枚举和 NPE 概念的基本理解。我的代码如下。 (此代码适用于 Enigma 密码机)
void displayMenu() {
System.out.println("MAIN MENU");
System.out.println();
Stream.of(menuChoice.values()).map(stream -> stream.ordinal() + ". " + stream.msg).forEach(System.out::println);
System.out.println();
}
public enum menuChoice {
QUIT("Quit the Enigma", EnigmaMachine.instance.quitAction),
ENCRPYT("Encrypt", EnigmaMachine.instance.encryptAction),
DECRYPT("Decrypt", EnigmaMachine.instance.decryptAction);
private String msg;
public Runnable action;
private menuChoice(String message, Runnable r) {
this.msg = message;
this.action = r;
}
}
menuChoice getUserChoice() {
System.out.print("Please enter your choice: ");
int choice = s.nextInt();
return menuChoice.values()[choice];
}
在 QUIT 常量上,我正在使用一个可运行的设置:
final Runnable quitAction = () -> {
EnigmaMachine.instance.running = false;
};
堆栈跟踪是这样的:
Exception in thread "main" java.lang.ExceptionInInitializerError
at enigmamachine.EnigmaMachine.displayMenu(EnigmaMachine.java:24)
at enigmamachine.EnigmaMachine.<init>(EnigmaMachine.java:85)
at enigmamachine.EnigmaMachine.main(EnigmaMachine.java:91)
Caused by: java.lang.NullPointerException
at enigmamachine.EnigmaMachine$menuChoice.<clinit>(EnigmaMachine.java:30)
... 3 more
Java Result: 1
我的构造函数是这样的:
public EnigmaMachine() {
this.running = true;
while (this.running) {
displayMenu();
getUserChoice().action.run();
}
}
对象实例是在我的代码底部的 main 函数之上定义的。
static EnigmaMachine instance;
public static void main(String[] args) {
instance = new EnigmaMachine();
}
我不一定在寻找解决方案,但也许是对我正在处理的事情的更相关的解释。 非常感谢。
您遇到这个问题只是因为 EnigmaMachine.instance
在此处 QUIT("Quit the Enigma", EnigmaMachine.instance.quitAction)
调用时仍然是 null
。你不应该在你的构造函数中调用 displayMenu()
因为它太早了,你应该调用它一个方法来避免这个问题。
例如,您可以向 class 添加一个方法开始,如下所示:
public void start() {
this.running = true;
while (this.running) {
displayMenu();
getUserChoice().action.run();
}
}
然后在main
方法中调用next
instance = new EnigmaMachine();
instance.start();