Trust and Non-Public Members

by Charles Miller on August 14, 2003

Paul (no obvious surname) found himself with the problem: "I have class Foo, and I want to make sure that it is only ever instantiated by a particular Factory". He solved this problem using a nifty inner-class hack

Leaving aside the questionable aspects of this "class-and-factory" design, it's an interesting exercise in how sometimes we want to exert too much control over our code. This is how I'd solve the problem, if it were up to me:

class Foo {
    /**
     * This class should NEVER be instantiated by 
     * anything except the FooFactory!
     * 
     * @author Charles
     */
     Foo() {}
}

Anything more complicated than this is obfuscation. The constructor is package-private, and there is an implicit understanding that you don't call any non-public method on a class unless you understand exactly what you're doing. Methods are made non-public because they allow greater access to the object than is considered 'safe' for the rest of the world. You are being given permission to poke at the object's innards because by your position (coding in the same package as it) you are trusted to know what you are doing. And this at the very least means reading the Javadoc.

It's tempting to try to make it impossible for people to write bad code. It's also often a waste of time. It's OK for people to be able to write bad code in situations where they should know better. As such, making the constructor package-private and adding a comment is sufficient. Anyone working in the package should know better with that much signposting. Anything more is obfuscation.

Previously: Gosling on Java

Next: Charles Audio-blogs