13.1 The Form of a Java Binary
While many Java binary files are likely to be in exactly the class
file format specified by the The Java Virtual Machine Specification, this specification does not
mandate the use of any specific binary file format. Rather, it specifies properties
that any binary format for compiled types must obey. A number of these properties are specifically chosen to support source code transformations that preserve
binary compatibility.
The requirements are:
- Binary formats for Java programs must be defined and processed to respect the specifications of loading (§12.2), linking (§12.3) and initialization (§12.4) of class and interface types.
- A reference to another class or interface type must be symbolic, using the fully qualified name of the type as determined at compile time.
- A reference to a field of another class or interface must be resolved at compile time to a symbolic reference to the class or interface in which the field is declared, plus the simple name of the field. (Including the exact class or interface in which the field is declared makes the binaries more robust, since adding another field with the same name, even in a subclass, cannot cause confusion at link time. This rule does mean, however, that moving a field to a superclass is not a binary compatible change; see §13.4.5 for a discussion.) The reference must also include a symbolic reference to the declared type of the field so that the verifier can check that the type is as expected. References to fields that are
static
, final
, and initialized with compile-time constant expressions are resolved at compile time to the constant value that is denoted. No reference to such a constant field should be present in the code in a binary file (except in the class or interface containing the constant field, which will have code to initialize it), and such constant fields must always appear to have been initialized; the default initial value for the type of such a field must never be observed. See §13.4.8 for a discussion.
- A reference to a method or constructor must be resolved at compile time to a symbolic reference to the class or interface in which the denoted method or constructor is declared, plus the signature of the method or constructor. (As for fields, this makes the binaries more robust, with the caveat that such a method cannot be moved to a superclass without leaving a forwarding method behind; see §13.4.5 for a discussion.) A reference to a method must also include either a symbolic reference to the return type of the denoted method or an indication that the denoted method is declared
void
and does not return a value. The signature of a method must include all of the following:
- The simple name of the method
- The number of parameters to the method
- A symbolic reference to the type of each parameter
The signature of a constructor must include both:
- The number of parameters to the constructor
- A symbolic reference to the type of each parameter
A Java binary representation for a class or interface must also contain all of the
following:
- If it is a class and is not class
java.lang.Object
, then a symbolic reference to the direct superclass of this class
- A symbolic reference to each direct superinterface, if any
- A specification of each field that is not
private
declared in the class or interface, given as the simple name of the field and a symbolic reference to the type of the field
- If it is a class, then the signature of each constructor, as described above
- For each method that is not
private
declared in the class or interface, its signature and return type, as described above
- The code needed to implement the class or interface:
- For an interface, code for the field initializers
- For a class, code for the field initializers, the static initializers, and the implementation of each method or constructor that is not declared
private
If a Java system defines a binary format that represents a group of classes and interfaces comprised by an entire package, then this binary format need not expose information about fields, methods, or constructors that are declared with default (package) access.
The following sections specify the changes that may be made to class and interface type declarations without breaking compatibility with pre-existing binaries. The Java Virtual Machine and its standard class
file format support these changes; other Java binary formats are required to support these changes as well.