Java:子包的可见性?
我的项目中有两个包: odp.proj
和odp.proj.test
。 有一些方法,我只想看到这两个包中的类。 我怎样才能做到这一点?
编辑:如果没有Java的子包的概念,有没有办法解决这个问题? 我有一些特定的方法,我只想让这个包的testing者和其他成员可用。 我应该把所有东西都扔进同一个包里吗? 使用广泛的反思?
你不能。 在Java中没有一个子包的概念,所以odp.proj和odp.proj.test是完全独立的包。
你的软件包的名字暗示这里的应用程序是用于unit testing的。 使用的典型模式是把你想testing的类和unit testing代码放在同一个包(在你的情况下是odp.proj
),但在不同的源代码树中。 所以你可以把你的类放在src/odp/proj
,你的testing代码放在test/odp/proj
。
Java没有指定“公共”,“私有”或“保护”时没有指定“包”访问修饰符,这是默认访问修饰符。 使用“包”访问修饰符,只有odp.proj
类odp.proj
访问这些方法。 但请记住,在Java中,不能依赖访问修饰符来实施访问规则,因为使用reflection,任何访问都是可能的。 访问修饰符仅仅是暗示性的(除非存在限制性安全pipe理器)。
odp.proj
和odp.proj.test
之间没有什么特别的关系 – 它们恰好被命名为明显相关的。
如果odp.proj.test包简单地提供testing,则可以使用相同的包名称( odp.proj
)。 像Eclipse和Netbeans这样的IDE将使用相同的包名称,但使用JUnit语义创build单独的文件夹( src/main/java/odp/proj
和src/test/java/odp/proj
)。
请注意,这些IDE将为odp.proj
方法生成testing,并为其不存在的testing方法创build适当的文件夹。
当我在IntelliJ中这样做时,我的源代码树如下所示:
src // source root - odp - proj // .java source here - test // test root - odp - proj // JUnit or TestNG source here
编辑:如果没有Java的子包的概念,有没有办法解决这个问题? 我有一些特定的方法,我只想让这个包的testing者和其他成员可用。
它可能取决于你的动机不显示他们,但如果唯一的原因是你不想污染公共接口的东西只是为了testing(或其他内部的东西),我会把方法在一个单独的公共接口,并使“隐藏”方法的使用者使用该接口。 它不会阻止他人使用界面,但我看不出为什么你应该。
对于unit testing,如果有可能不重写批次,请按照build议使用相同的包。
如果不把访问修饰符放在方法的前面,你可以说它是私有的。
看看下面的例子。
package odp.proj; public class A { void launchA() { } } package odp.proj.test; public class B { void launchB() { } } public class Test { public void test() { A a = new A(); a.launchA() // cannot call launchA because it is not visible } }
使用PackageVisibleHelper类,并在PackageVisibleHelperFactory冻结之前保持私有,我们可以在任何地方调用launchA(通过PackageVisibleHelper)方法:)
package odp.proj; public class A { void launchA() { } } public class PackageVisibleHelper { private final PackageVisibleHelperFactory factory; public PackageVisibleHelper(PackageVisibleHelperFactory factory) { super(); this.factory = factory; } public void launchA(A a) { if (factory == PackageVisibleHelperFactory.INSTNACNE && !factory.isSampleHelper(this)) { throw new IllegalAccessError("wrong PackageVisibleHelper "); } a.launchA(); } } public class PackageVisibleHelperFactory { public static final PackageVisibleHelperFactory INSTNACNE = new PackageVisibleHelperFactory(); private static final PackageVisibleHelper HELPER = new PackageVisibleHelper(INSTNACNE); private PackageVisibleHelperFactory() { super(); } private boolean frozened; public PackageVisibleHelper getHelperBeforeFrozen() { if (frozened) { throw new IllegalAccessError("please invoke before frozen!"); } return HELPER; } public void frozen() { frozened = true; } public boolean isSampleHelper(PackageVisibleHelper helper) { return HELPER.equals(helper); } } package odp.proj.test; import odp.proj.A; import odp.proj.PackageVisibleHelper; import odp.proj.PackageVisibleHelperFactory; public class Test { public static void main(String[] args) { final PackageVisibleHelper helper = PackageVisibleHelperFactory.INSTNACNE.getHelperBeforeFrozen(); PackageVisibleHelperFactory.INSTNACNE.frozen(); A a = new A(); helper.launchA(a); // illegal access new PackageVisibleHelper(PackageVisibleHelperFactory.INSTNACNE).launchA(a); } }