In the spirit of Neil and Josh/Will’s Java Puzzlers, here is one I just recently ran into:

Given the following block of code:

        PropertyChangeSupport changes = new PropertyChangeSupport(this);
        PropertyChangeListener l = new PropertyChangeListener(){

            public void propertyChange(PropertyChangeEvent evt) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

        };
        changes.addPropertyChangeListener("foo", l);

        for( PropertyChangeListener remove : changes.getPropertyChangeListeners() ){
            changes.removePropertyChangeListener(remove);
        }

        System.out.println(changes.getPropertyChangeListeners().length);

What will this snippet print:

  1. 0
  2. 1
  3. Throws an Exception
  4. Other

Answer after the jump.

The answer is, it prints “1″.

When you add a PropertyChangeListener to the PCS class using a property name, the listener is returned in the .getPropertyChangeListeners() array. However, you can only remove a listener added in this way using the .removePropertyChangeListener( “propertyName”, listener) method.

The PropertyChangeListenerProxy class provides a self-filtering on events based on property name which you can subclass and add it using the unindexed .addPropertyChangeListener(listener) method. Without looking at the internals of PropertyChangeSupport, it seems to me this would get noisy if you had a lot of listeners, though. Since all events are going to all of the proxies then they are filtering before they call the .propertyChange(PropertyChangeEvent evt) method, rather than only firing events to the listeners that care about them.

update: There are actually some stranger thing about this issue. Scan the comments for more information!