Keep interface implementations private

Let’s say you’re writing a class and at some point you need to spawn off some work in a different thread. A common solution is to have your class implement Runnable and pass yourself to the Thread constructor:

class Something implements Runnable {
    public void doSomething() {
        new Thread(this).start();
    }

    @Override // Runnable
    public void run() {
        // Do work.
    }
}

The trouble with that approach is that you’ve advertised to the world that your class is runnable, and you’ve let them call your run() method, but that’s no one’s business but yours. You’re not really runnable from their point of view. You’ve given them incorrect information and too much power.

It’s even worse to subclass Thread, since you’ve blown your only chance to subclass something else, and you’ve completely lost control over your thread, which anyone else can now manipulate or destroy.

Pass in an anonymous class instead, and have it call a private method:

class Something {
    public void doSomething() {
        new Thread(new Runnable() {
            @Override // Runnable
            public void run() {
                doWork();
            }
        }).start();
    }

    private void doWork() {
        // Do work.
    }
}

Or, since Thread implements Runnable already, you can write the above more simply as:

class Something {
    public void doSomething() {
        new Thread() {
            @Override // Runnable
            public void run() {
                doWork();
            }
        }.start();
    }

    private void doWork() {
        // Do work.
    }
}

This takes a few more lines of code but sends no incorrect message to onlookers, and prevents them from calling your run() method at the wrong time or in the wrong thread. The above also allows you to pass parameters to your method:

class Something {
    public void doSomething(final int count) {
        new Thread() {
            @Override // Runnable
            public void run() {
                doWork(count);
            }
        }.start();
    }

    private void doWork(int count) {
        // Do work.
    }
}

This isn’t possible when passing yourself as an implementer of the interface. Though you could get around that with fields, using fields as globals is a bad idea (see Avoid fields for communication between methods).

Similarly, only implement Future, Callable, ThreadFactory, Executor, MouseListener, and other similar interfaces, if you really want other classes to treat you as such. Don’t do it just as a way to have a method (such as addMouseListener()) call one of your methods as a callback.