Home > database >  Java *sealed* classes/interfaces: maximum number of subclasses
Java *sealed* classes/interfaces: maximum number of subclasses

Time:06-28

What is the maximum number of sub classes that can be listed for a sealed class (analogous for interfaces):

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

Does the language actually define a limit; i.e., is it virtually infinite at the level of the language?

If there is no such limit at the level of the language, it seems that an implementation still must have a technical limit. Somewhere there ought to be a list that stores some kind of representation of the sub classes permitted. I would expect a 16 or 32 bit integer to be used then.

CodePudding user response:

The JLS (Java Language Spec) generally includes no limits at all. Even though there are lots of limits. It's the JVMS (Java Virtual Machine Specification) that includes limits. This makes sense: A lot of these limits are fundamentally related to bytecode and class file format concepts, which are ideas that the JLS doesn't know about - in other words, even if the JLS wanted to, it couldn't possibly describe the limits in terms that are defined in the JLS.

For example, the max size of a method is 'measured' in bytecode instructions, which isn't a java-the-language concept in the first place.

Hence, the JVMS is where to look for such limits. For example JVM Spec §4.7.31 (as provided by @akarnokd, good find!).

There are limits on:

  • Number of methods in a type
  • Number of fields in a type
  • Number of interfaces in your implements list
  • Number of parameters a method can have
  • Size of a method's "frame" (how much stack space it needs)
  • Size of the number of local slots. These last 2 bullets more or less translate in java-the-language to a limit on number of local vars you can have.
  • Number of bytecode per method. Easiest way to run into this limit is by having a large finally block attached to a try with loads of catch blocks. The finally block is replicated for all of them. Nest try blocks for exponential bytecode growth!
  • Number of type params you can have in signatures.
  • Number of entries in the constant pool. This would appear in java-the-language as limits on the number of literals you can include in a single class.

I'm sure I'm forgetting a few.

There are further limits that are in no spec; such as memory and heap size limits, and a lot of details about command line switches (for example, on a bunch of JVM releases and OSes, any -Xss parameter (that sets stack sizes) that isn't evenly divisible by a 'word boundary', whose definition depends on OS and architecture, was completely ignored) - all unspecced.

Some of that makes sense (the exact specifics on precisely how much heap you really can reserve depends on too many factors to attempt to document in detail), some of it really doesn't (the fact that the tool switches act like they are highly specced, having 2 layers of 'less specced' in both -X and -XX doesn't really mesh well with the idea that neither the JVMS nor the JLS mentions the tools available or their command line switches in much detail.

CodePudding user response:

The answer here is correct, but I'll add that even in JVMS 4.7.31 (the PermittedSubtypes attribute), you won't find a specific limit. But since every permitted subtype must correspond to a Constant_Class_info in the constant pool, and the constant pool is limited to 64K entries, and each Class constant has an associate String constant, so you could not get more than 32K in any case. Of course, you probably have other things in your class too, which compete for the constant pool, so you won't get that either. But the answer is, effectively "thousands".

  • Related