I ran into a peculiar issue I was curious about (and would like to find a workaround for).
If I declare a variable NODES in my class:
private static final String NODES = "nodes";
Everything works ok.
However, if I declare the variable in an interface:
public interface MSMConstants {
public static final String NODES = "nodes";
}
and implement that interface in the class that uses the variable NODES,
I get a null pointer exception upon my first use of NODES.
Any ideas on what’s going on here?
Lines that are crashing:
lr_fontSize.setSelectedItem(((VisualItem)m_vis.getVisualGroup(NODES).tuples().next()).getFont().getSize());
SearchQueryBinding sq = new SearchQueryBinding((Table) m_vis.getGroup(NODES), "label",
(SearchTupleSet) m_vis.getGroup(Visualization.SEARCH_ITEMS));
The second is inside a constructor; the first is also inside a constructor, but for an object that is instantiated from the second.
Stack trace was requested:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at prefuse.data.query.SearchQueryBinding.<init>(SearchQueryBinding.java:53)
at edu.stanford.folding.msmexplorer.MSMExplorer.<init>(MSMExplorer.java:703)
at edu.stanford.folding.msmexplorer.MSMExplorer.graphView(MSMExplorer.java:1538)
at edu.stanford.folding.msmexplorer.MSMExplorer.graphView(MSMExplorer.java:1526)
at edu.stanford.folding.msmexplorer.MSMExplorer$1.actionPerformed(MSMExplorer.java:202)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6375)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6140)
at java.awt.Container.processEvent(Container.java:2083)
at java.awt.Component.dispatchEventImpl(Component.java:4737)
at java.awt.Container.dispatchEventImpl(Container.java:2141)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
at java.awt.Container.dispatchEventImpl(Container.java:2127)
at java.awt.Window.dispatchEventImpl(Window.java:2482)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:684)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:643)
at java.awt.EventQueue$1.run(EventQueue.java:641)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:657)
at java.awt.EventQueue$2.run(EventQueue.java:655)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:654)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
There is no technical difference. We can declare
final staticconstants on interfaces and classes and use them. Both approaches that you’ve shown should work.But constant declarations don’t match too well with the concept of an interface. I know, that a lot of people use interfaces as “repositories for constants” that’s definitely not their purpose.
One reason to do that was that it provided a simple way to “inherit” constant definitions through “implementing” those constant holder interface.
But now we have static imports and though there’s no need to “abuse” the interfaces anymore.