java JMenuItem Nullpointerexception(重写swing类时初始化时出错)
我正在做一个项目,并取得了良好的进展,直到我偶然发现一个意想不到的例外。它是由一个JMenuItem的初始化引起的,有些令人惊讶,就像我以前做过类似的事情一样。我发现类(class2)工作正常,如果它不是JMenuItem(class4)的子类。我还找到了一个解决方法(class3),但我仍然想知道,我做错了什么。我搜索了一个答案,但没有找到答案,可能是因为搜索条件不好。有人有什么想法吗java JMenuItem Nullpointerexception(重写swing类时初始化时出错),java,swing,nullpointerexception,initialization,jmenuitem,Java,Swing,Nullpointerexception,Initialization,Jmenuitem,我正在做一个项目,并取得了良好的进展,直到我偶然发现一个意想不到的例外。它是由一个JMenuItem的初始化引起的,有些令人惊讶,就像我以前做过类似的事情一样。我发现类(class2)工作正常,如果它不是JMenuItem(class4)的子类。我还找到了一个解决方法(class3),但我仍然想知道,我做错了什么。我搜索了一个答案,但没有找到答案,可能是因为搜索条件不好。有人有什么想法吗 import javax.swing.JMenuItem; class class1 { publ
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();
}
}
当我执行这个类时,就会发生这种情况:
$ 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)
$javac class1.java
$java-showversion class1
java版本“1.8.0_73”
Java(TM)SE运行时环境(build 1.8.0_73-b02)
Java HotSpot(TM)64位服务器虚拟机(构建25.73-b02,混合模式)
类别3:0,g
班级3:1,d
类别4:0,c
线程“main”java.lang.NullPointerException中出现异常
在class2.getText(class1.java:29)
位于javax.swing.AbstractButton.setModel(AbstractButton.java:1779)
位于javax.swing.JMenuItem.setModel(JMenuItem.java:173)
位于javax.swing.JMenuItem。(JMenuItem.java:150)
位于javax.swing.JMenuItem。(JMenuItem.java:110)
在class2。(class1.java:24)
在class1.main(class1.java:8)
最后,一个NullPointerException问题不是您的问题
如果您查看或为方法提供了一个@Override
注释,您将看到public String getText()
是一个超级方法的重写,特别是一个JMenuItem的父级AbstractButton的方法,并且似乎超级的构造函数正在调用它,在调用实例初始值设定项块之前调用它,这将导致NPE
此问题说明了以下情况下可能发生的风险:
- 您可以扩展复杂的类李>
- 类在其构造函数中调用非最终实例方法(Swing作者这样做真让人羞愧)
- 静态字段不是以静态方式初始化的
- 倾向于使用组合而不是继承,尤其是在处理大型复杂类时
- 对静态字段使用静态初始值设定项块
- 除非有明确的需要,否则避免使用静态字段
- 在创建方法时检查您是否在无意中重写实例方法。特别是当我无意中为一个扩展了JPanel的类重写了
和public int getX()
,然后想知道为什么我的布局管理器不能正常工作时,我被这一点烧坏了public int getY()