English

FAQ: Why should developers who use or reference any of the listeners in MapObjects-Java API create strong references to them?

Question

Why should developers who use or reference any of the listeners in MapObjects-Java API create strong references to them?

Answer

The MapObjects—Java API uses a special approach to handling event listeners. This impacts the way that these listeners are stored within an EventMulticaster, which is used to broadcast the appropriate events to these listeners.

MapObjects—Java code does not retain "strong" references to application-defined listener instances, but instead maintains "weak" references to those listener instances; see the link in Related Information below for a description of references. This means that application code must retain a strong reference; otherwise, listener instances will most likely be garbage-collected almost immediately.

An appropriate place for application code to retain a strong reference to an event listener is as a member field of the enclosing class. When the enclosing class instance is garbage-collected, the listener will be as well.

This is done to avoid memory leaks. Refer to the javadoc-generated API reference for the class com.esri.mo2.util.EventMulticaster, which is the parent class for all event multicasters within MapObjects.

This impacts all listener components defined by MapObjects—Java but not those defined elsewhere such as in Java 2 SDK, Standard Edition.

Here is a typical example of code that you might ordinarily expect to work but will not work because of this change:

Code:
import com.esri.mo2.map.dpy.DisplayListener;

import com.esri.mo2.ui.bean.Map;

class MyApp extends javax.swing.JFrame {

MyApp() {

Map map1 = new Map();

this.getContentPane().add(map1);

// At this point, the application adds an instance of an

// "anonymous" class that implements DisplayListener.

map1.addDisplayListener(new DisplayListener() {

// .... listener implementation

});

}

}

Instead, here is what could be done to ensure that the application-defined listener is not immediately garbage-collected and works as expected:

Code:
import com.esri.mo2.map.dpy.DisplayListener;

import com.esri.mo2.ui.bean.Map;

class MyApp extends javax.swing.JFrame {

DisplayListener listener;

MyApp() {

Map map1 = new Map();

this.getContentPane().add(map1);

// The application constructs a reference to the listener

// that is retained within the enclosing MyApp instance

listener = new DisplayListener() {

// .... listener implementation

};

map1.addDisplayListener(listener);

}

}

Related Information