1

I am working on a project and made good progress until I stumbled upon an unexpected exception. It is caused by intiatiating a JMenuItem and somewhat surprising, as I did similar things before. I found out that the class (class2) works ok, if it is not a subclass of JMenuItem (class4). I also found a workaround (class3), but I still would like to know, what I am doing wrong. I searched for an answer, but did not come up with an answer, probably because of poor search terms. Anyone any ideas?

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();
    }
}

And this happens, when I execute the 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)
dnz
  • 23
  • 5
  • Nicely asked question by the way, one where you've posted an extremely simplified program that has no fluff, and that fully illustrates your problem. This is refreshing to see in a newbie to this site. – Hovercraft Full Of Eels Feb 27 '16 at 19:36

1 Answers1

1

Finally, a NullPointerException question that is not your typical NPE question.

If you look into the JMenuItem API or if you give your method an @Override annotation, you'll see that public String getText() is an override of a super method, specifially a method of JMenuItem's parent, AbstractButton, and it appears that the super's constructor is calling it, calling it before your instance initializer block is called, and this is resulting in your NPE.

This problem illustrates the risks that can occur when:

  • You extend complex classes.
  • Classes call non-final instance methods within their constructors (shame on the Swing authors for doing this)
  • Static fields are not initialized in a static way.

Solutions for you include:

  • Favoring using composition over inheritance, especially when dealing with large and complex classes.
  • Using a static initializer block for your static fields.
  • Avoid using static fields unless there is a definite need.
  • Check when creating methods that you're not unknowingly overriding an instance method. I've been burned by this in particular when I unknowingly overrode public int getX() and public int getY() for a class that extended JPanel and then wondered why my layout managers weren't working right.
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373