12

I found this construct in some code.

Is there any benefit to have a private static class implement A? This reminded me of the Pimpl idiom in C++. Is there any benefit to using the Pimpl idiom in Java?

public abstract class A {
    public void doStuff();

    public static A getNewInstance() {
       return new AImpl();
    }

    private static class AImpl extends A {
        public void doStuff()  {
           ....
        }    
    } 

}
Chip
  • 3,226
  • 23
  • 31

1 Answers1

18

Is there any benefit to have a private static class implement A?

Well, it hides the implementation away completely, so from an encapsulation point of view it's quite nice. One situation I've seen this in a few times is custom comparators. For example:

public class Person
{
    public static final Comparator<Person> NAME_COMPARATOR = new NameComparator();
    public static final Comparator<Person> AGE_COMPARATOR = new AgeComparator();

    // Name, age etc properties

    private static class NameComparator implements Comparator<Person>
    {
        ...
    }

    private static class AgeComparator implements Comparator<Person>
    {
        ...
    }
}

There's no real need for the comparator implementation classes to be visible outside Person, and it's nice to be able to get an instance easily via the public static field.

No callers need to know the implementation - there could just be one comparator class which takes parameters, for example - they just express which comparator they want via the constants. (You could equally use an enum for this, of course.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Thanks for the answer. But isn't it better to have `NameComparator` and `AgeComparator` as non-public classes? I'm not sure, but doesn't adding a static inner class make it binary incompatible? – Chip Aug 10 '12 at 06:00
  • @Chip: If they're non-public classes outside `Person`, they're still available in the same package when they really don't need to be. Adding a static inner class *may* change the serialization UID unless you specify it explicitly, but binary serialization in Java is so horrible that I don't use it anyway. I don't believe it will affect binary compatibility of simply running the code. – Jon Skeet Aug 10 '12 at 06:02
  • Thanks Jon. It makes sense if it does not break binary compatibility. For the design to be flexible, I would want to be able to add another class, say `AImpl2` the same way, and not break older clients. – Chip Aug 10 '12 at 06:12
  • I was excited about this, but I just found out that private variables inside NameComparator and AgeComparator are visible to each other. Guess they are not "first class" classes. – Chip Aug 11 '12 at 00:08
  • @Chip: Yes, the accessibilty of private members within nested classes is interesting... but it's at least *somewhat* limited. – Jon Skeet Aug 11 '12 at 06:34
  • Yes.. its a decision between "hiding from the rest of the package" vs "hiding from each other". Not ideal, but I'll have to go with one or the other – Chip Aug 11 '12 at 08:23