【问题标题】:Java Language naming convention for .class files [closed].class 文件的 Java 语言命名约定 [关闭]
【发布时间】:2017-10-18 13:11:15
【问题描述】:

我了解到here,即使这是最佳实践,尽管大多数编译器都要求您这样做,但将 .class 文件以它们包含的公共类命名并不那么严格,至少来自语言规范观点。

我搜索了 JLS 和 JVM 规范,但无法找到解决该主题的实际章节。我觉得这个问题根本没有得到处理,这让我觉得很奇怪。

如果存在,Oracle 官方文档在哪里可以确认或揭穿以下声明?

.class 文件赋予与它们包含的公共类相同的名称——不管它们是否这样做——是必须的,但根据JLS,这并不那么严格。从 JLS 的角度来看,由编译器决定是否设置这样的限制。

【问题讨论】:

  • 我会使用章节或页码在出版物/著作中进一步引用该主题。
  • 请注意,每个 .java 源可能有多个 .class 文件,即每个创建的内部类都有一个。对于命名内部类,它们通常具有 [toplevel_public_class]$[inner_class].class 格式,对于匿名内部类,它们通常具有 [toplevel_public_class]$[number].class 格式。我不知道这是一个规则还是只是一些标准的做法,但这是一个例子,.class 文件并不总是与顶级类的名称完全匹配(尽管它是名称的重要部分)。
  • 顺便说一句,我在这里可能错了,但从运行时的角度来看,文件名根本不重要,因为文件包含所有必要的信息。但是,具有匹配的文件名使人类或基于文本的操作更容易(例如,尝试在 jar 中查找类以加载它),因为您不必扫描每个文件以找到正确的文件。对源文件的限制可能也主要是为了防止人类把它搞砸;)
  • 如果你要确认,事实上,.class 文件没有严格要求以它们包含的公共类命名:你的生活将如何改善?如果你知道这样的需求确实存在,它真的那么糟糕吗?
  • @Thomas 正如您所说,Java 链接器需要知道它必须加载哪个 .class 文件,并且在大型项目中找到正确的文件需要很长时间。但奇怪的是,即使所有主要编译器和 Oracle NetBeans IDE 都遵循此规则,JLS 也从未解决此问题。

标签: java jvm documentation jls


【解决方案1】:

JLS §13.1., The Form of a Binary 解决了这个问题:

程序必须编译成 Java 虚拟机规范,Java SE 8 版指定的 class 文件格式,或者编译成可以由类加载器映射到该格式的表示形式用Java编程语言编写的。

因此,您根本不需要将编译后的代码作为.class 文件提供,只要您有一个能够加载代码表示的类加载器实现。请注意,在此级别上,例如将映射数据传递给ClassLoader.defineClass 时,类文件的文件名根本不存在。 JLS 和 JVM 两个规范始终使用术语“类文件”同义词来表示“类文件格式中的字节序列”,而不是“文件系统或 zip 存档中的条目”,因此,在全部。

这也符合 Java 9 的发展方向,交付类库是一种自定义的、可能经过优化的库格式,而不是一个装满 .class 文件的 zip 容器。

不过,将包含不同表示形式的文件命名为 .class 结尾是非常不鼓励的。

您引用的陈述有点奇怪。它以

开头

.class 文件与它们包含的公共类同名是必须的,...

.class 文件根本不必包含public 类。在目前的形式中,它最多包含一个类,不必是public。但它也可能包含一个虚拟类来传递 package 元信息,或者从 Java 9 开始,一个模块规范。

此外,为了在默认查找规则下找到,例如使用URLClassLoader,您不会为.class 文件提供包含类的名称,而是使用其短名称并将其放置在从其限定名称的包组件派生的目录结构/路径中。

但是第二部分

……但根据 JLS,这并不那么严格。从 JLS 的角度来看,由编译器决定是否设置这样的限制。

是正确的。如上所述,甚至不需要提供类文件。比较

JLS §1., Introduction:

Java 编程语言通常编译为Java 虚拟机规范,Java SE 8 版中定义的字节码指令集和二进制格式。

注意“通常”这个词

JVMS §2.1., The class File Format:

Java 虚拟机执行的编译代码使用独立于硬件和操作系统的二进制格式表示,通常(但不一定)存储在文件中,称为class 文件格式。

“通常(但不一定)”……

【讨论】:

  • 谢谢!关于声明的第一部分,我应该指定“如果它们根本包含公共类”......并不是说 .class 文件必须包含公共类,但如果它们包含,他们应该(从你的回答来看,这只是一个好的编程习惯,但他们仍然应该)以该类的名称命名。
  • 关键点是,如果您希望标准查找算法(如URLClassLoader 实现的)起作用,则必须遵循命名约定。否则,你将不得不实现你自己的加载器(尽管如果只是命名不同,它不会那么难)。在 Java 9 中,不仅有一个新的类加载器实现,还有一个特殊的 FileSystem 实现,工具可以使用它来读取模块。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多