Coming Up for Air

A Possibly Silly Question about Java Visibility

Thursday, December 20, 2018 |

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:

1
2
3
4
5
6
7
8
9
package com.steeplesoft.visibilitytest;

public class Class1 {
    public void publicMethod() { }

    protected void protectedMethod() { }

    private void privateMethod() { }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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() { }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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.

Search

    Quotes

    Sample quote

    Quote source

    About

    My name is Jason Lee. I am a software developer living in the middle of Oklahoma. I’ve been a professional developer since 1997, using a variety of languages, including Java, Javascript, PHP, Python, Delphi, and even a bit of C#. I currently work for Red Hat on the WildFly/EAP team, where, among other things, I maintain integrations for some MicroProfile specs, OpenTelemetry, Micrometer, Jakarta Faces, and Bean Validation. (Full resume here. LinkedIn profile)

    I am the president of the Oklahoma City JUG, and an occasional speaker at the JUG and a variety of technical conferences.

    On the personal side, I’m active in my church, and enjoy bass guitar, running, fishing, and a variety of martial arts. I’m also married to a beautiful woman, and have two boys, who, thankfully, look like their mother.

    My Links

    Publications