Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java "new" keyword in parameter

Tags:

java

oop

I've been looking through a lot of OOP Design Patterns lately, and I've run into some strange things I've never seen before:

Button button =  new Button(shell, SWT.PUSH);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
    // Handle the selection event
    System.out.println("Called!");
    }
}); 

Specfically, what does this do (eg. what does the "new" keyword do here)?:

    button.addSelectionListener(new SelectionAdapter() {

Second question:

private void notifyListeners(Object object, String property, String oldValue, String newValue) {
   for (PropertyChangeListener name : listener) {
      name.propertyChange(new PropertyChangeEvent(this, "firstName", oldValue, newValue));
   }
}

This is a snippet from an observer design pattern. To my new understanding, the name.propertyChange(...) creates an object of PropertyChangeEvent and through Java's observer pattern implementation, automatically notifies the observers by sending this new object's information to the observers (or something very similar to this). Is this correct?

like image 212
Shaku Avatar asked Aug 01 '13 01:08

Shaku


2 Answers

Here, the new keyword is creating an anonymous class.

This is useful when you need a listener to perform some action, and you'd like to keep your code grouped together, and/or the class is "one-off", meaning it has no use elsewhere.

Here's a link to sun's tutorial on anonymous classes. All the normal rules of classes apply. You need to implement abstract methods, or all methods when creating an interface.

Scope is a little different as you can access variables declared in the class your anonymous class is nested within. However, you can't access local variables from an anonymous class unless those local variables are declared final. For instance:

Button button =  new Button(shell, SWT.PUSH);
final String someString = "hello world!";
button.addSelectionListener(new SelectionAdapter() { 
    @Override
    public void widgetSelected(SelectionEvent e) {
        // Handle the selection event
        System.out.println(someString);
    }
});

If someString were declared in more global scope, this would not be the case.

To your second question:

Yes. You are correct, that's what's happening in the snippet. Notice a new PropertyChangeEvent is being created every time? This is so listeners appearing earlier in the list don't modify the PropertyChangeEvent for items appearing later in the list.

like image 158
William Morrison Avatar answered Nov 18 '22 02:11

William Morrison


First of all, this is a Java-specific syntax: there is no comparable syntax in C#, where you must either create an anonymous class extending object, or create an instance of a named class.

In Java this syntax lets you create an anonymous subclass of SelectionAdapter, overriding any methods as you see fit. This is equivalent to creating a named class that extends SelectionAdapter, overriding any methods as you do in the curly braces following the SelectionAdapter() constructor call, and then using the name of that derived class in the call of addSelectionListener. The only difference is that such derived class would have a name, while the anonymous class from your example does not have a name * available to programmers.

* Internally anonymous classes do have names: you can see them if you look at the list of class files generated by the Java compiler. Files with dollar signs and numbers in their names correspond to anonymous classes.

like image 29
Sergey Kalinichenko Avatar answered Nov 18 '22 04:11

Sergey Kalinichenko