java JMenuItem Nullpointerexception(初始化错误,覆盖摆动 class)
java JMenuItem Nullpointerexception (error on initialization, when overriding a swing class)
我正在做一个项目并取得了很好的进展,直到我偶然发现了一个意外的异常。它是由启动 JMenuItem 引起的,有点令人惊讶,因为我之前做过类似的事情。我发现 class (class2) 工作正常,如果它不是 JMenuItem (class4) 的子 class。我也找到了解决方法 (class3),但我仍然想知道我做错了什么。我搜索了一个答案,但没有找到答案,可能是因为搜索条件不佳。有人有什么想法吗?
import javax.swing.JMenuItem;
class class1 {
public static void main(String[] f) {
System.err.println(new class3(0));
System.err.println(new class3(1));
System.err.println(new class4(0));
new class2(1);
}
}
class class2 extends JMenuItem {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class2(int e) {
super();
b = e;
}
public String getText() {
return a[b];
}
public String toString() {
return class2.class + ": " + b + ", " + getText();
}
}
class class3 extends JMenuItem {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class3(int e) {
super();
b = e;
}
public String getText() {
if ( b == 0 ) return "g";
return a[b];
}
public String toString() {
return class3.class + ": " + b + ", " + getText();
}
}
class class4 {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class4(int e) {
super();
b = e;
}
public String getText() {
return a[b];
}
public String toString() {
return class4.class + ": " + b + ", " + getText();
}
}
当我执行 class:
时,就会发生这种情况
$ javac class1.java
$ java -showversion class1
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
class class3: 0, g
class class3: 1, d
class class4: 0, c
Exception in thread "main" java.lang.NullPointerException
at class2.getText(class1.java:29)
at javax.swing.AbstractButton.setModel(AbstractButton.java:1779)
at javax.swing.JMenuItem.setModel(JMenuItem.java:173)
at javax.swing.JMenuItem.<init>(JMenuItem.java:150)
at javax.swing.JMenuItem.<init>(JMenuItem.java:110)
at class2.<init>(class1.java:24)
at class1.main(class1.java:8)
最后,一个 NullPointerException 问题不是你的typical NPE question。
如果您查看 JMenuItem API 或给您的方法添加 @Override
注释,您会发现 public String getText()
是对超级方法的重写,特别是方法JMenuItem 的父级 AbstractButton,看起来超级的构造函数正在调用它,在调用您的实例初始化程序块之前调用它,这会导致您的 NPE。
此问题说明了在以下情况下可能发生的风险:
- 您扩展了复杂的 classes。
- 类 在其构造函数中调用非最终实例方法(Swing 作者这样做是可耻的)
- 静态字段不是以静态方式初始化的。
适合您的解决方案包括:
- 倾向于使用组合而不是继承,尤其是在处理大型和复杂的 classes 时。
- 为您的静态字段使用静态初始化程序块。
- 除非有明确的需要,否则避免使用静态字段。
- 在创建方法时检查您是否在不知不觉中覆盖了实例方法。当我在不知不觉中为扩展 JPanel 的 class 覆盖
public int getX()
和 public int getY()
然后想知道为什么我的布局管理器无法正常工作时,我尤其为此感到恼火。
我正在做一个项目并取得了很好的进展,直到我偶然发现了一个意外的异常。它是由启动 JMenuItem 引起的,有点令人惊讶,因为我之前做过类似的事情。我发现 class (class2) 工作正常,如果它不是 JMenuItem (class4) 的子 class。我也找到了解决方法 (class3),但我仍然想知道我做错了什么。我搜索了一个答案,但没有找到答案,可能是因为搜索条件不佳。有人有什么想法吗?
import javax.swing.JMenuItem;
class class1 {
public static void main(String[] f) {
System.err.println(new class3(0));
System.err.println(new class3(1));
System.err.println(new class4(0));
new class2(1);
}
}
class class2 extends JMenuItem {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class2(int e) {
super();
b = e;
}
public String getText() {
return a[b];
}
public String toString() {
return class2.class + ": " + b + ", " + getText();
}
}
class class3 extends JMenuItem {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class3(int e) {
super();
b = e;
}
public String getText() {
if ( b == 0 ) return "g";
return a[b];
}
public String toString() {
return class3.class + ": " + b + ", " + getText();
}
}
class class4 {
static String[] a;
int b;
{
a = new String[2];
a[0] = "c";
a[1] = "d";
}
public class4(int e) {
super();
b = e;
}
public String getText() {
return a[b];
}
public String toString() {
return class4.class + ": " + b + ", " + getText();
}
}
当我执行 class:
时,就会发生这种情况$ javac class1.java
$ java -showversion class1
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
class class3: 0, g
class class3: 1, d
class class4: 0, c
Exception in thread "main" java.lang.NullPointerException
at class2.getText(class1.java:29)
at javax.swing.AbstractButton.setModel(AbstractButton.java:1779)
at javax.swing.JMenuItem.setModel(JMenuItem.java:173)
at javax.swing.JMenuItem.<init>(JMenuItem.java:150)
at javax.swing.JMenuItem.<init>(JMenuItem.java:110)
at class2.<init>(class1.java:24)
at class1.main(class1.java:8)
最后,一个 NullPointerException 问题不是你的typical NPE question。
如果您查看 JMenuItem API 或给您的方法添加 @Override
注释,您会发现 public String getText()
是对超级方法的重写,特别是方法JMenuItem 的父级 AbstractButton,看起来超级的构造函数正在调用它,在调用您的实例初始化程序块之前调用它,这会导致您的 NPE。
此问题说明了在以下情况下可能发生的风险:
- 您扩展了复杂的 classes。
- 类 在其构造函数中调用非最终实例方法(Swing 作者这样做是可耻的)
- 静态字段不是以静态方式初始化的。
适合您的解决方案包括:
- 倾向于使用组合而不是继承,尤其是在处理大型和复杂的 classes 时。
- 为您的静态字段使用静态初始化程序块。
- 除非有明确的需要,否则避免使用静态字段。
- 在创建方法时检查您是否在不知不觉中覆盖了实例方法。当我在不知不觉中为扩展 JPanel 的 class 覆盖
public int getX()
和public int getY()
然后想知道为什么我的布局管理器无法正常工作时,我尤其为此感到恼火。