Java包访问很奇怪。这是有意的吗?

时间:2012-08-18 12:41:35

标签: java compilation package

我做了一个实验,我扩展了一个java.lang包类,无法访问包方法或字段(没有public或protected的方法或字段)。确定。

然后我在源代码根目录下的'java.lang'中添加了我的扩展,并再次尝试编译。所以包访问限制只是装饰性的(你需要将它放在与其他类相同的位置,因此用户可以通过导入java.lang找到它)并且它们实际上也可能是公共的,因为没有实际的弱访问级别在这里? (至少保证它是一个扩展覆盖)。

2 个答案:

答案 0 :(得分:2)

如果将代码放入名为java.lang的包中,则意味着您的代码属于该包,因此您确实可以访问原始java.lang中描述的“包”方法。

想一想:在一个项目中你有“包”访问级别方法,你想要对它们进行单元测试。您可以在同一个包中的类中执行此操作,这意味着完全位于同一目录中,或者您可以拥有2个单独的目录:src和test,具有相同的包命名。这样,单元测试可以在与代码相同的包中定义,但它们位于磁盘上的不同位置。

答案 1 :(得分:2)

包的概念存在于Java中,以便在类成员的可访问性中提供额外的粒度级别。由于Java中类加载机制的灵活性,当您在与此类C相同的包中声明自己的类时,它们无法限制您访问类C的包级成员和属性。

某些规范强制执行更具限制性的访问策略,如OSGI。 OSGI附带了 bundle 的附加概念,缺少Java语言本身。 Bundles是一组打包在一个jar中的类。他们在清单文件中声明了哪些类以及哪些包 export ,其他包可以访问。那些未导出的包和类严格无法从其他包中访问。

此外,即使导出了类C,也无法从另一个包访问包的类C的包级方法和属性。 OSGI类加载器不允许您从已被另一个bundle“拥有”的包中加载一个类。

如果您对这些关于可访问性和打包的问题感兴趣,请查看Jigsaw project,它打算在Java中重新设计模块化,并且应该出现在Java SE的下一个版本中(Java SE 8,尽管我我不确定它是否没有被推迟。)