Coming Up for Air

A Possibly Silly Question about Java Visibility

This morning, I was asked a question by a coworker that we both thought we knew the answer to: if a method is protected, can other classes see that method? The answer surprised us: maybe. :) It’s a pretty simple, basic question, but I thought I’d mention it in case there’s a beginner wondering, or more senior developers, such as myself and my team mate, that just have it wrong. :)

The official Java docs provide a nice chart, which I’ve reproduced here:

Modifier Class Package Subclass World

public

Y

Y

Y

Y

protected

Y

Y

Y

N

no modifier

Y

Y

N

N

private

Y

N

N

N

What we knew was that protected members were visible to subclasses. What we expected, though, was they would not be visible to any other classes. What we found accidentally when writing tests, and what the table clearly indicates, is that the method is visible to classes in the same package. To demonstrate, I cobbled together a simple project:

package com.steeplesoft.visibilitytest;

public class Class1 {
    public void publicMethod() { }

    protected void protectedMethod() { }

    private void privateMethod() { }
}
package com.steeplesoft.visibilitytest;

public class Class2 {
    public Class1 publicInstance = new Class1();
    protected Class1 protectedInstance = new Class1();
    private Class1 privateInstance = new Class1();

    public void publicMethod() {
        publicInstance.publicMethod();
        publicInstance.protectedMethod();
        publicInstance.privateMethod(); // Error - not visible
    }

    protected void protectedMethod() { }

    private void privateMethod() { }
}
package com.steeplesoft.visibilitytest.sub;

import com.steeplesoft.visibilitytest.Class1;
import com.steeplesoft.visibilitytest.Class2;

public class Class3 {
    public Class1 class1 = new Class1();
    protected Class2 class2 = new Class2();

    public void publicMethod() {
        class1.publicMethod();
        class2.publicMethod();

        class1.protectedMethod(); // Error - not visible
        class1.privateMethod(); // Error - not visible

        class2.protectedMethod(); // Error - not visible
        class2.privateMethod(); // Error - not visible

        class2.secondInstance(); // Error - not visible
        class2.thirdInstance(); // Error - not visible
    }
}

As expected (for those sharper than I, it seems), Class2 can see Class1.publicMethod and Class1.protectedMethod, but not Class1.privateMethod. Class3, however, can only see Class2.publicMethod, but not the other two. It can also only see the publicInstance field, but neither protectedInstance nor privateInstance.

Moral of the story: if you’re trying to hide methods from other classes, protected may not be the answer your looking for.

tags: Java

Quotes

Sample quote

Quote source