4

I am trying find an example in the Java API where the Null Object pattern is being used ?

I have seen this statement on stackoverflow that ComponentAdapter, FocusAdapter, KeyAdapter, MouseAdapter are actually Null Objects:

Adapter pattern: InputStreamReader and OutputStreamWriter NOTE: ContainerAdapter, ComponentAdapter, FocusAdapter, KeyAdapter, MouseAdapter are not adapters; they are actually Null Objects. Poor naming choice by Sun.

I am not sure how ?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Dusan
  • 105
  • 7
  • 2
    @NathanHughes That's probably what OP is quoting. – shmosel Jul 31 '19 at 19:58
  • What about [`Optional.empty()`](https://github.com/netroby/jdk9-dev/blob/master/jdk/src/java.base/share/classes/java/util/Optional.java#L86-L90), where `EMPTY` would be the null object? As an example of usage. – Vince Jul 31 '19 at 20:49

2 Answers2

3

IHMO ComponentAdapter, KeyAdapter and all these AWT classes don't match to the null object pattern intention :

In most object-oriented languages, such as Java or C#, references may be null. These references need to be checked to ensure they are not null before invoking any methods, because methods typically cannot be invoked on null references.

But these match to its description :

Instead of using a null reference to convey absence of an object (for instance, a non-existent customer), one uses an object which implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation is that a null object is very predictable and has no side effects: it does nothing.

Matching to a description/implementation is finally just an implementation detail. For example mocks, stubs and dummy objects match also to this description. Should we consider it as Null objects ? I don't think so.

These AWT classes look to be convenient implementations to spare some mandatory implementations with empty body inside.
For example, a JFrame subclass could implement only methods of KeyListener that needs with a KeyAdapter :

public class FooFrame extends JFrame {

    public FooFrame(){

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                if (e.getKeyCode()== KeyEvent.VK_ENTER){
                    // do something
                }
            }
        });
    }
}

But with KeyListener it should implement all of them (with an empty body for them that we will not use) :

addKeyListener(new KeyListener() {
    @Override
    public void keyTyped(KeyEvent e) {
        if (e.getKeyCode()== KeyEvent.VK_ENTER){
            // do something
        }
    }
    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
});

The important thing here is that using or not these "adapter" classes will not protect your code more against NullPointerException. So definitively no, these don't look like Null objects.

So do we have null object pattern in the JDK ? Maybe, but anyway not sure and not common.

Source : https://en.wikipedia.org/wiki/Null_object_pattern


Edit for existing examples

For example, some aspects such as caching or security have "real" implementations in production environments while in local or integration environments you may want not to use these implementations because expensive or complex in terms of overhead or setup.
In this case, you generally use a no-op implementation rather than assigning a null reference for them that would force you to check the no nullity of the at each time that these fields are used such as :

if (cacheManager != null){
   // use cache manager
}

For example, Spring provides org.springframework.cache.support.NoOpCacheManager for no-op CacheManager implementations.

As a side note, you can notice that ComponentAdapter, KeyAdapter, and so for... are also no-op implementations (same description as NoOpCacheManager) but their intention is difference : these AWT classes prevent useless code / boiler plate code while the second prevents the no nullity checks.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Sorry, I didn't get the point you are trying to make... *"mocks, stubs and dummy objects match also to this description"* - No, they don't. They are used to simulate/mimic/replace an object, not "to convey the absence of an object". *"Should we consider it as Null objects?"* - If a mock object happened to have empty methods and it effectively does nothing, we can call it a null object. Why not? It's also unclear how exactly the classes *"don't match to the null object pattern intention"* – Andrew Tobilko Jul 31 '19 at 20:46
  • @Andrew Tobilko : that is rather clear since the intention of the pattern is preventing null pointer exception but these don't prevent them. – davidxxx Jul 31 '19 at 20:55
  • How come? If you scroll down to the Java section on the page you linked and replace `NullAnimal` with any of these classes, you will see it can prevent NPEs as well as `NullAnimal` – Andrew Tobilko Jul 31 '19 at 21:03
  • The intention of these AWT classes is not creating not null instances but creating empty implementations to allow you to override the method(s) that you want to use. You will never use a null reference as variable of these classes since if you use them it means that de facto you want to override a behavior and so instantiate them. – davidxxx Jul 31 '19 at 21:09
1

One of the characteristics of a null object is that it does nothing and its methods are empty. All the classes you mentioned possess this property, so you can identify them as examples of the null object pattern.

The naming choice isn't poor. They all are adapters, in the first place.

A strong counter-argument could be that they are abstract which makes them impossible to be initialised.

Even if we know a simple workaround

FocusAdapter adapter = new FocusAdapter() {};
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142