java JMenuItem Nullpointerexception(覆盖swing类时的初始化错误)

问题描述:

我正在开发一个项目,并取得了不错的进展,直到遇到意外的异常。这是由于引入JMenuItem而引起的,有点令人惊讶,因为我之前做过类似的事情。如果它不是JMenuItem(class4)的子类,我发现类(class2)工作正常。我还发现了一个解决方法(class3),但我仍然想知道,我做错了什么。我搜索了一个答案,但没有拿出答案,可能是因为搜索条件不好。任何任何想法?java JMenuItem Nullpointerexception(覆盖swing类时的初始化错误)

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) 
+0

由你到哪儿去发布一个没有绒毛,且充分说明您的问题以极其简单的程序的方式,一个奈斯利问的问题。这是令人耳目一新的看到这个网站的新手。 –

最后一个NullPointerException的问题,是不是你的typical NPE question

如果你看看JMenuItem API或者如果你给你的方法的@Override注解,你会看到public String getText()是个超级方法的重写,specifially的JMenuItem的母公司AbstractButton中的方法,并出现了超类的构造函数调用它,在你的实例初始化块被调用之前调用它,这导致你的NPE。

这个问题说明时可能出现的风险:

  • 您扩展复杂的类。
  • 类在其构造函数中调用非最终实例方法(Swing作者为此而感到羞愧)
  • 静态字段未以静态方式初始化。

解决方案为您包括:

  • 大型和复杂的类打交道时偏袒使用超过组成继承,更是如此。
  • 对静态字段使用静态初始化块。
  • 避免使用静态字段,除非有明确的需求。
  • 检查创建的方法,你不是无意中覆盖实例方法。我特别被烧毁这个时候我在不知不觉中推翻public int getX()public int getY()对于扩展的JPanel,然后不知道为什么我的布局管理器不工作的权利类。