包 - 私有类中的`public`修饰符

时间:2016-02-22 08:12:17

标签: java

最近,我正在编写一个类,我决定将其作为包私有(即,没有访问修饰符,或者默认一个)。它有一个内部类和一些private辅助方法,以及一个旨在由同一个包中的类使用的方法。所有这些班级成员都是static。但后来我有一个想法:这个方法应该有public访问修饰符还是没有访问修饰符,比如包含它的类?

一方面,由于类本身是包私有的,因此只能在其包中访问和使用它,因此没有实际的理由来创建方法public。但同时,在语义上,此方法旨在成为类的 public 特性,即,旨在外部使用的类的特性,因此修改它的意义是有意义的。这样访问。

对于那些喜欢看代码的人,

final class DummyRemover {

    private DummyRemover() {

    }

    public static int remove(Map<String, ClassNode> classMap) {
        return 0;
    }

    // ...
}

,或者

final class DummyRemover {

    private DummyRemover() {

    }

    // Notice the modifier.
    static int remove(Map<String, ClassNode> classMap) {
        return 0;
    }

    // ...
}

这里最好的选择是什么?是否有一个经验法则来决定在这种情况下使用哪些访问修饰符?

3 个答案:

答案 0 :(得分:5)

为什么方法应该具有比其封闭类更高的可见性有两个原因:

1。封闭类是基类

...用于子类扩展,最终可能是公共的,并且手头的方法应该是公开可用的。 E.g。

abstract class Base {
    public void x() {}
}

public class Sub extends Base {
}

// Now, everyone can call:
new Sub().x();
但是,通常,如果这是您的意图,您仍然会在界面中声明方法x()。即使您没有在设计方面在接口中声明x(),最好将基本方法保持在与其类相同的可见性级别,并“打开”子类中的方法,因为将更清楚地传达意图:

abstract class Base {
    void x() {}
}

public class Sub extends Base {
    /** public Javadoc here */
    @Override
    public void x() {
        super.x();
    }
}

我认为没有任何理由可以将此方法应用于静态方法,如您的情况。

2。方法必须是公开的

...因为它从接口实现了一个方法。遗憾的是,Java不提供包私有或私有接口方法。所以下面是通常的,即使没有任何子类,即使接口本身可能是包私有的(甚至是嵌套的私有):

final class Y implements X {
    @Override
    public void x() {}
}

这(不幸的是)也适用于接口上的静态类,它们只能是公共的:

interface I {
    /* implicitly public */ static void x() {}
}

答案 1 :(得分:3)

这有两种思想流派:

一个群体更喜欢添加不必要的修饰符(例如,在这种情况下为public,私有类中为private)作为代码&#34;中的文档形式。例如,这是Eric Lippert在his answer on this related C# question中所支持的观点。

另一组更喜欢永远不会添加没有功能效果的源代码:如果public不是做任何事情那么它就不属于您的源代码

我想我现在已经坚定地进入了第二阵营,但我理解第一阵营的论点,我认为它并不像它最初出现的那样切割和干燥。合理的人可以不同意,这就是为什么(如大括号和空白)这是你应该在项目风格指南中决定一次然后再也不再辩论的事情。 : - )

答案 2 :(得分:0)

我个人认为制作方法public可能会误导读者。 另一方面,它支持可扩展性(如果该类应该公开,则更改更容易)。

每当我需要在可读性和可扩展性之间做出选择时,我会选择 YAGNI 原则并选择可读性。

有关YAGNI的更多信息,请参阅维基:https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it