比类访问修饰符更少限制的成员访问修饰符有什么用处?

9

假设我有一个类,它有一些成员,而这些成员的访问修饰符比类本身更不严格。

一个具体的例子可能是:

package apples;

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

据我理解,一个比成员访问修饰符更严格的类访问修饰符将覆盖较不严格的成员访问修饰符。因此,较不严格的成员访问修饰符应该根本没有影响。
- 我的理解正确吗?
- 如果不是,会有什么后果?
- 有哪些合法的理由可以使用较不严格的成员访问修饰符?
- 最后,有哪些最佳实践需要遵循?
我还进行了一些实验,因为我认为一旦开始传递函数引用,它可能会产生后果,但即使在那种情况下,访问修饰符似乎也没有关系。
我构造的情况如下:
- apples.B提供一个公共方法bla(),返回对apples.A.foo的引用。 - 然后,pizzas.C调用apples.B.bla以获取对A.foo的引用并调用它。 - 因此,A.foo()对C不可见,只能通过B.bla()间接访问
我进行了测试,无论我是否将foo()的访问修饰符设置为包私有,都没有影响。
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;
    }
}


3
这种设计最常见的原因是为了利用非公共类来实现公共API方法(例如来自接口或扩展抽象类的方法)。 JDK本身就有很多这样的类(例如, java.util.Collections.SingletonSet <E>java.util.Collections 中被声明为 private)。 - ernest_k
1个回答

7

我的理解是正确的吗?

是的。

有哪些合理的理由可以使用较少限制的成员访问修饰符呢?

有两个原因:

  • 有时,您正在实现一个接口;接口方法必须是 public
  • 它使您更容易更改类的总体访问权限。例如,如果您将您想公开的所有方法都标记为 public,即使在包私有类中,以后要将类公开只需向类声明添加 public 即可。

最后,有什么最佳实践要遵循吗?

这是一个观点问题,不适合放在 Stack Overflow 的问题或回答中。按照您和/或您的团队认为合理的方式执行,或者按照您的团队的样式指南告诉您要做什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接