In the following Java code, PropertyChangeListener is implemented in two ways: 1) using a class that implements PropertyChangeListener interface, and 2) using a method reference.
According to the API, the addPropertyChangeListener method takes, as argument, an object of type PropertyChangeListener. The first approach (Commented line in main method in PointTest class) is implemented in this way.
But in the second approach, just a method reference is passed to the addPropertyChangeListener method (i.e. handlePropertyChange). Surprisingly, the method is void! So, my questions are "How does the second approach work? and why does the code compile in the first place?!"
class Point {
private int x, y;
private PropertyChangeSupport pcs;
public Point(int x, int y) {
this.x = x;
this.y = y;
pcs = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
int oldX = this.x;
this.x = x;
pcs.firePropertyChange("x", oldX, x);
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
class PointTest {
public static void main(String[] args) {
Point p = new Point(1, 2);
// p.addPropertyChangeListener(new myPropertyChangeListener()); // <--- first approach
p.addPropertyChangeListener(PointTest::handlePropertyChange); // <--- second approach
p.setX(10);
p.setX(20);
}
public static void handlePropertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if("x".equals(propertyName)) {
System.out.println("x has changed:");
System.out.println("\t old: " + e.getOldValue());
System.out.println("\t new: " + e.getNewValue());
}
}
}
class myPropertyChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if("x".equals(propertyName)) {
System.out.println("x has changed:");
System.out.println("\t old: " + e.getOldValue());
System.out.println("\t new: " + e.getNewValue());
}
}
}