Whats the use of less restrictive member access modifiers than the class access modifier?

Stefan D. :

Say I have a class with some members, and the members have a less restrictive access modifier than the class itself.

A concrete example could be:

package apples;

class A { // package private
    public int foo() { // public (=> less restrictive than *package private*)
        return 42;
    }
}

To my understanding a class access modifier that is more restrictive than the member access modifier, will override the less restrictive member access modifiers. So a less restrictive member access modifier should have no effect at all.

  • Is my understanding correct?
    • If not, what are the consequences?
  • What could be valid reasons to have less restrictive member access modifiers?
  • Finally, what are there best practice to follow?

I also did some experimenting because I thought it might have consequences once I start passing function references around, however even then the access modifier does not seem to matter.

The situation that I constructed is the following:

  • apples.B provides a public method bla() that returns a reference to apples.A.foo.
  • Then pizzas.C calls apples.B.bla to obtain a reference to A.foo and calls it.
  • So A.foo() is not directly visible to C, but is only indirectly accessible via B.bla()

I tested it and it does not make a difference whether I make the access modifier of foo() package private or not.

package apples;

import java.util.function.IntSupplier;

public class B {
    public IntSupplier getReferenceToAFoo() {
        A aInstance = new A();
        return aInstance::foo;
    }
}
package pizzas;

import apples.B;

import java.util.function.IntSupplier;

public class C {
    private int callAFooIndirectly() {
        B bInstance = new B();
        IntSupplier intsupplier = bInstance.getReferenceToAFoo();
        return intsupplier.getAsInt();
    }

    public static void main(String[] args) {
        C cInstance = new C();

        int i = cInstance.callAFooIndirectly();
        System.out.println(i);
        assert 42 == i;
    }
}

T.J. Crowder :

Is my understanding correct?

Yes.

What could be valid reasons to have less restrictive member access modifiers?

Two reasons:

  • Sometimes, you're implementing an interface; interface methods must be public
  • It makes it easier to change the overall access of your class. For instance, if you mark all the methods that you'd ever want to be public public, even in a package-private class, then later all you have to do to make the class public is add public to the class declaration.

Finally, what are there best practice to follow?

That's a matter of opinion, so not well-suited to a Stack Overflow question or answer. Do what seems reasonable to you and/or your team, and/or do what your team's style guide tells you to do.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=304458&siteId=1