In Java, private classes can be used in signatures of public interfaces. This makes no sense.

I had a situation the other day that I wanted to break one line down into multiple lines for readability. But it wasn't possible. If I wrote the code as one line it worked; multiple lines it didn't. This is rather inconsistent! The following public class demonstrates the situation:

public class PublicObject {
    private class PrivateObject { }

    private PrivateObject x;
    public void setX(PrivateObject x) { this.x=x; }
    public PrivateObject getX() { return x; }
}

As you see, PublicObject instances are allowed to provide public methods which take and return PrivateObject instances, however that doesn't make a lot of sense, as you can't write client code which creates or manipulates PrivateObject instances.

But in fact that's not true. Java does, in a very few places, use type inference (more info here) to guess the type of objects, to save the programmer typing. And the public/private rule enforcement seems to be:

So the following code works:

myPublicObject.setX(myPublicObject.getX());

but the following code doesn't:

PrivateObject x = myPublicObject.getX();
myPublicObject.setX(x);

And the reason the first line works is that, although the code is clearly using PrivateObject instances, it doesn't ever use the word "PrivateObject" in the source code.

Surely, whether you explicitly reference the class in your code, or implicitly using the language's type inference, are just syntactic differences only, and you should either be allowed to do both or neither.

(In .NET, the equivalent code does indeed not compile.)

P.S. I recently created a nerdy privacy-respecting tool called When Will I Run Out Of Money? It's available for free if you want to check it out.

This article is © Adrian Smith.
It was originally published on 8 Feb 2011
More on: Java | FAIL