【问题标题】:Java: Is there a way to put nested classes in a separate file?Java:有没有办法将嵌套类放在单独的文件中?
【发布时间】:2018-06-23 08:01:52
【问题描述】:

我有一个大约 4,000 行长的 Java 类(很多方法)。然后这个类使用了大约 200 个只有它需要的小类,所以还有 4000 行代码。

如果这是 C#,我会将那些其他的放在一个部分类文件中,这样不同的文件,但它们将保持私有嵌套类仅对父类可见。

有没有办法在 Java 中做到这一点?我不是要求某些方法位于不同的文件中,而是要求私有嵌套类位于不同的文件中。

谢谢 - 戴夫

【问题讨论】:

  • 有什么理由不将它们作为类放在同一个包中? (顺便说一下,一个 4000 行长的类文件,大约 3800 行太长了)
  • 这些类是静态的,还是在 4000 行的类中使用了一些“很多方法”?
  • 把这个类和所有的子类放在一个单独的包中,然后给子类包私有可见性。
  • @Stewart:我认为任意限制类的长度并不是一个好主意。没有上下文,我们真的无法知道这是否太多。你会在github.com/nodatime/nodatime/tree/master/src/NodaTime 中找到很多大约一千行长的类型,但我通常不觉得它们太大。如果你有相当多的方法,每个方法都有大量的文档,它可以很容易地安装。
  • @David 默认可见性 包私有。什么意思?

标签: java partial-classes


【解决方案1】:

你不能将一个类只对另一个类私有,同时将它放在不同的文件中。

不使用类访问修饰符

您可以做的是将类放在单独的文件中,不带访问修饰符(省略“public”),这将使它们成为包私有,即仅在其自己的包中可见。另见the official Access Control tutorial

UtilClasses.java:

package OurPackage;

class UtilClass1
{
}
class UtilClass2
{
}

MainClass.java:

package OurPackage;

public class MainClass
{
   UtilClass1 iAmAUtilClass;
}

使用接口或继承

您也可以通过在嵌套类中省略访问修饰符来实现类似的接口或继承。这也是包私有的,但在某些情况下这可能比上述更可取,因为它避免了所有嵌套类都位于顶层。

BaseInterface.java:

package OurPackage;

interface BaseInterface
{
   class UtilClass1
   {
   }
}

MainClass.java:

package OurPackage;

public class MainClass implements BaseInterface
{
   UtilClass1 iAmAUtilClass;
}

您也可以使用基类而不是接口并扩展它,效果大致相同。

您无需实现BaseInterface 即可访问其嵌套类,但如果您不这样做,则需要使用BaseClass.UtilClass1 而不仅仅是UtilClass1

【讨论】:

    【解决方案2】:

    内部私有类不能被“提取”并且仍然只对一个特定的类可见。 cmets 中已经提到了一种解决方案:创建一个包含“主”类和所有先前内部类的包,并使内部类包可见。这也将允许您创建单元测试来测试内部类的正确功能,这目前很可能不会发生,因为目前单元测试无法“访问”内部类。

    在 C++ 中声明类之间的“友谊”之类的概念在 Java 中不存在。

    【讨论】:

      【解决方案3】:

      您可以用顶级的内部类替换内部类,但您必须手动重写很多东西,编译器会自动为您与内部类关系关联。对于虚拟机来说,内部类并没有什么特别之处,它只是与外部类在同一个包中的另一个类,名字很花哨。但是编译器在后台创建了很多辅助构造,你必须手动重建(或者让一些重构工具为你做):

      • 内部类可以引用外部this 实例,方法是在外部类名称前面加上前缀。您需要将外部 this 传递给内部构造函数,并将其存储在 outerThis 之类的字段中以获取访问权限。
      • 在源代码中,您可以直接调用外部类方法。你需要像outerThis.method() 一样重写它。这同样适用于字段。
      • 为了使私有外部方法和字段变得可访问,编译器会为您创建桥结构。您必须自己更改访问修饰符或创建包私有桥接方法。

      最后,您将拥有至少包可见的内部类,并且比原来的内部类更冗长,但另一方面,您将获得更好的隔离性和可测试性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-12
        • 2010-12-05
        • 1970-01-01
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多