代码之家  ›  专栏  ›  技术社区  ›  gameover

为什么Java在编译时生成多个.class文件?

  •  7
  • gameover  · 技术社区  · 15 年前

    在Java中,在编译时,我们为源文件中定义的每个类(包括嵌套类和接口)获得一个.class文件。

    生成多个.class文件的原因是什么?
    是为了简化类的可重用性吗?
    为什么不生成一个.class类?

    3 回复  |  直到 15 年前
        1
  •  7
  •   Stephen C    15 年前

    回答@jon skeet的反问:

    然后另一个类引用了bar,所以JVM需要它的代码…你建议它如何找到文件?

    假设(假设)Java类文件格式通过嵌套在最外层类的类文件中表示嵌套/内部类。条形图的二进制名称是“ Lsome/pkg/Foo$Bar; “。类装入器 能够 在“”处拆分名称 $ 字符,使用第一部分定位foo的类文件,然后导航到嵌入的bar类表示。

    我认为内部/嵌套类具有独立类文件的真正原因是历史的。IIRC,Java 1不支持嵌套或内部类,因此相应的类文件格式不需要处理它们。当Java 1.1被创建(支持内部/嵌套类)时,Sun希望类文件格式与Java 1编译器生成的类文件兼容。因此,他们选择使用保留的 $ “二进制类名中的字符。

    第二个可能的原因是与假设的嵌入式格式相比,平面格式简化了类加载。

    最后,他们没有(并且仍然没有)令人信服的理由不使用平面文件格式。当一些程序员想使用 Class.forName() 但这是非常罕见的…解决办法是直截了当的。

        2
  •  12
  •   Jon Skeet    15 年前

    JVM需要能够找到给定类的代码,并给出其名称。如果源文件名和代码文件名之间可能没有关系,并且您希望代码文件名基于 来源 文件名,您希望它如何加载代码?

    例如:假设我要编译包含类栏的foo.java。

    然后另一个类引用了bar,所以JVM需要它的代码…你建议它如何找到文件?

    注意,在.NET中有一个独立的部署单元称为 装配 -对类型的引用也包括程序集名称,但这与您所建议的略有不同。

        3
  •  2
  •   stacker    15 年前

    这是一个关于编译单元的设计决策,由开发人员做出。 编译类通常组合在一个JAR文件中。

    从中提取 Java Language Spec

    7.3编制单位 compilationUnit是以下语法的目标符号(_§2.1) Java程序。

    在不同的编译单元中声明的类型可以循环地相互依赖。 Java编译器必须安排同时编译所有此类类型。