Java programming idiom : Private implementation class
Asked Answered
M

1

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()  {
           ....
        }    
    } 

}
Midnight answered 10/8, 2012 at 5:48 Comment(0)
E
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.)

Ebracteate answered 10/8, 2012 at 5:52 Comment(6)
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?Midnight
@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.Ebracteate
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.Midnight
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.Midnight
@Chip: Yes, the accessibilty of private members within nested classes is interesting... but it's at least somewhat limited.Ebracteate
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 otherMidnight

© 2022 - 2024 — McMap. All rights reserved.