提问者:小点点

Java*密封*类/接口:最大子类数


可以为密封类列出的子类的最大数量是多少(类似于接口):

public sealed class Foo permits A, B, C {
   // How many sub classes can  ^^^^^^^
   // be listed here?
}

语言是否真的定义了一个限制;即,在语言层面上它实际上是无限的吗?

如果在语言层面上没有这样的限制,那么实现似乎仍然必须有技术限制。某个地方应该有一个列表,存储允许的子类的某种表示。我希望那时使用16或32位整数。


共1个答案

匿名用户

JLS(Java语言规范)通常不包含任何限制。尽管有很多限制。是JVMS(Java虚拟机规范)包含限制。这是有道理的:许多这些限制从根本上与字节码和类文件格式概念有关,这些概念是JLS不知道的——换句话说,即使JLS愿意,它也不可能用JLS中定义的术语来描述限制。

例如,方法的最大大小是用字节码指令“测量”的,而字节码指令首先不是java语言的概念。

因此,JVM是寻找这些限制的地方。例如,JVM规范§4.7.31(由@akarnokd提供,很好!)。

有以下限制:

  • 类型中的方法数
  • 类型中的字段数
  • 实现列表中的接口数
  • 方法可以具有的参数数
  • 方法“框架”的大小(它需要多少堆栈空间)
  • 本地插槽数的大小。最后2个项目符号或多或少用java语言翻译为您可以拥有的本地var数量的限制。
  • 每个方法的字节码数。达到此限制的最简单方法是将一个大的最终块附加到加载了catch块的try。最终块被复制给所有这些块。嵌套try块以实现指数字节码增长!
  • 您可以在签名中拥有的类型参数数。
  • 常量池中的条目数。这将在java语言中显示为对可以包含在单个类中的文字数量的限制。

我肯定我忘记了一些。

没有规范中的进一步限制;例如内存和堆大小限制,以及关于命令行开关的许多详细信息(例如,在一系列JVM版本和操作系统上,任何不能被“字边界”(其定义取决于操作系统和体系结构)均匀划分的参数(设置堆栈大小)都被完全忽略),所有这些都是未加密的。

其中一些是有意义的(关于您真正可以保留多少堆的确切细节取决于太多的因素,无法尝试详细记录),有些确实没有(事实上,工具开关的行为就像它们是高规格的,在-X-XX中都有两层“规格较低的”,这与JVM和JLS都没有详细提到可用的工具或其命令行开关的想法不太吻合。