Contents | Prev | Next | Index | The JavaTM Virtual Machine Specification

# Summary of Clarifications and Amendments

This appendix discusses the differences between the original version of The JavaTM Virtual Machine Specification and the present revision. Its purpose is twofold: to summarize what changes have been made and to explain why they were made.

Throughout this appendix, we refer to the original version of The JavaTM Virtual Machine Specification (that is, the first published version of this book) as the original specification or the original specification of the Java virtual machine. We refer to the current book as the revised specification. We denote the first edition of The JavaTM Language Specification as simply The JavaTM Language Specification.

The revised specification seeks to clarify points that gave rise to misunderstanding and to correct ambiguities, errors, and omissions in the original specification.

Except for the treatment of floating-point computation, the differences between the revised specification and its predecessor have no effect on valid programs written in the Java programming language. The revisions influence only how the virtual machine handles incorrect programs. In many of these instances, most implementations did not implement the original specification. The revised specification documents the intended behavior.

The most obvious changes are in the specification of floating-point types and operations; `class` file verification; initialization, loading, and linking; and the method invocation instructions. In addition, several other important corrections have been made.

The revised specification also fixes errors or clarifies issues that were brought to our attention by readers of the original specification.

While we have made every effort to correct as many problems as possible, we recognize that additional improvements would benefit this specification. In particular, we believe that the description of `class` file verification should be further refined, ideally to the point of constituting a formal specification. We anticipate that future revisions will address remaining weaknesses and correct any newly reported bugs, while retaining unchanged the semantics of the Java programming language.

The following sections discuss the changes to the original specification in greater detail and explain why the changes were necessary.

## Floating-Point Types and Operations

The original specification required that all single- and double-precision floating- point calculations round their results to the IEEE 754 single- and double-precision formats, respectively. The revised specification permits additional floating-point calculations to be done using IEEE 754 extended precision formats.

As a result of this change, implementations on processors that more naturally and efficiently support extended precision formats and floating-point operations on extended precision formats can deliver better performance for floating-point calculations. Implementations on processors that naturally and efficiently implement IEEE 754 single- and double-precision operations as mandated by the original specification may continue to do so. The floating-point behavior of any Java virtual machine implementation that conforms to the original specification also conforms to the revised specification.

## Changes to `class` File Verification

The most important clarification on the topic of `class` file verification is that every Java virtual machine implementation must in fact perform verification. This is stated unambiguously in the The JavaTM Language Specification. The original specification of the Java virtual machine contained several misleading sentences that led some readers to conclude that verification was optional.

The discussion of the `class` file format in Chapter 4 also corrects a number of small errors in the original specification. The most significant of these corrections are:

- Interfaces can contain methods other than class or interface initialization methods (`<clinit>` methods).

- The class reference in a `CONSTANT_Fieldref_info` can be an interface type since interfaces can contain `static` fields.

- Methods that are `native` or `abstract` cannot have a `Code` attribute.

- Multiple declarations of a field or method with the same name and descriptor are illegal.

All of the preceding changes correct misstatements in the original specification that were obviously untrue. In addition, `class` file verification no longer bans attempts to invoke `abstract` methods; see a complete discussion of this issue later in this appendix.

## Initialization

The JavaTM Language Specification and the original specification of the Java virtual machine contradict each other on the question of whether the element type of an array type must be initialized when an instance of the array type is created. The JavaTM Language Specification specifies that the element type should be initialized in this case, whereas the original specification of the Java virtual machine states that it should not. We have resolved this contradiction in favor of the original Java virtual machine specification. The JavaTM Language Specification is thus in error, and will be corrected in its next edition.

The evident confusion over the circumstances triggering initialization led us to reword the specification of when initialization occurs (§2.17.4). However, this reworded specification is equivalent to the original.

One of the original requirements was that a class would be initialized the first time one of its constructors is invoked. In the Java programming language, constructor invocation constitutes instance creation. Furthermore, since no instance method can be invoked if no instances exist, it is clear that the requirement that a class be initialized the first time one of its methods is invoked is relevant only for `static` methods. By similar reasoning, the requirement that a class be initialized if any of its fields is accessed applies only to `static` fields.

The original specification did not accurately describe the circumstances that would trigger initialization at the Java virtual machine level (see discussion later in this appendix). Section 5.5 now gives a simple and precise definition in terms of Java virtual machine instructions.

## Loading and Linking

Chapter 5, "Loading, Linking, and Initializing," has been completely rewritten (and retitled). Chapter 5 of the original specification was erroneous in several important respects. The new chapter corrects these errors and tries to be both clearer and more precise. The organization of the revised chapter closely follows the structure of the corresponding sections in Chapter 12 of The JavaTM Language Specification.

The key changes include the following:

- Clarifying that loading a class causes its superinterfaces to be resolved.

The description of class loading in the original specification did not state that resolving a class required its superinterfaces to be resolved. This was an error in early Java virtual machine implementations that has been corrected.

- Clarifying that resolution does not necessarily imply further linking.

The description of `CONSTANT_Class_info` resolution in Section 5.1.1 of the original specification implied that resolution of a reference to a class causes it to be linked. While this was true of Sun's Java virtual machine implementation, the description was more restrictive than The JavaTM Language Specification , which clearly states that Java virtual machine implementations have flexibility in the timing of linking activities. The revised specification of the Java virtual machine agrees with The JavaTM Language Specification on this issue.

- Clarifying that resolution does not imply initialization.

The description of `CONSTANT_Class_info` resolution in Section 5.1.1 of the original specification implied that resolution of a class causes it to be initialized. However, the original specification also included the contradictory statement that initialization should occur only on the first active use of a class. In a Java virtual machine implementation that performs lazy resolution, the distinction is subtle. In other implementations the distinction is much clearer. For example, eager resolution is explicitly allowed by The Java Language Specification. If resolution always provoked initialization, such an implementation would be forced to perform eager initialization, in clear contradiction to The JavaTM Language Specification. The contradiction is resolved by decoupling resolution from initialization.

A closely related problem is the statement in Section 5.1.2 of the original specification that the `loadClass` method of class `ClassLoader` can cause initialization to occur if its second argument is `true`. This contradicts The JavaTM Language Specification, which states that only loading and linking occur in this case. Again, the contradiction has been resolved to conform to The JavaTM Language Specification, for essentially the same reasons.

- Clarifying that class loading uses `ClassLoader.loadClass(String)`.

The original specification stated that when loading a class or interface using a user-defined class loader the Java virtual machine invokes the two-argument method `ClassLoader.loadClass(String,` `boolean)`. The purpose of the `boolean` argument was to indicate whether linking should take place. However, it was noted on page 144 of the original specification that this interface was likely to change. It was recognized that placing responsibility for linking on the class loader was both inappropriate and unreliable.

Beginning with JDK release 1.1, linking is handled directly by the Java virtual machine. An additional method `loadClass(String)` has also been added to class `ClassLoader`. This method may similarly be invoked by the Java virtual machine. The revised specification defines class loading in terms of the new method. The two argument version is still retained in the Java 2 platform v1.2 in the interests of compatibility, but plays no role in the revised specification.

- Making explicit requirements for type safe class loading.

The subtleties of type safe linkage in the presence of multiple, user-defined class loaders were not sufficiently appreciated when the original specification was written. It has subsequently become clear that a detailed description of loading constraints on runtime types is warranted. Of course, the presence of loading constraints is observable only by invalid programs.

- Specifying explicitly the rules for access control.

These rules follow from The JavaTM Language Specification, but were left implicit in the original specification. The rules correspond to the behavior of existing implementations.

- Indicating that more appropriate exceptions are thrown when a class or interface is invalid.

Section 5.1.1 of the original specification states that a `NoClassDefFoundError` should be thrown if the representation of a class or interface is invalid. However, both The JavaTM Language Specification and Section 2.16.2 of the original specification state that a `ClassFormatError` is thrown in this case. Clearly, a `ClassFormatError` is more appropriate.

- Clarifying that the class hierarchy is searched when resolving fields and methods.

The original specification was unclear as to whether, during method or field resolution, the referenced field had to be declared in the exact class referenced or could be inherited. This led to variations among Java virtual machine implementations and inconsistency between The Java Virtual Machine Specification and The JavaTM Language Specification. The revised specification gives a more precise description that agrees with the behavior of most implementations, but not with The JavaTM Language Specification. The JavaTM Language Specification will be corrected in its next edition.

This choice gives programmers the flexibility of moving methods and fields in the class hierarchy while retaining binary compatibility with previous implementations of their programs.

- Clarifying that an `AbstractMethodError` may not be raised during preparation.

The JavaTM Language Specification requires that adding a method to an interface be a binary compatible change. However, Sections 5.1.1 and 2.16.3 of the original specification require that preparation reject a class that has an `abstract` method unless that class is itself `abstract`. The latter requirement contradicts the former.

Consider the case of an interface I implemented by a class C that is not `abstract`. If a new method is added to I, C must implement it. However, if an old version of C is used together with the new version of I at run time, C will indeed have an `abstract` method. If preparation were to raise an `AbstractMethodError` in this case, adding a method to I would not have been a binary compatible change, since it would have resulted in a link-time failure. Consequently, the check at preparation time has been dropped. This change has implications for method invocation, as discussed below.

- Clarifying that interface method resolution may raise exceptions.

The description in Section 5.3 of the original specification omitted the checks required during interface method resolution. These checks (that the referenced interface exists and that the referenced method exists in that interface) are required by The JavaTM Language Specification and are performed by most widely used implementations of the Java virtual machine. The checks are documented in Section 5.4.3.4 of the revised specification.

- Specifying events triggering class or interface initialization.

As a consequence of the decoupling of class and interface initialization from resolution, it became necessary to specify when the Java virtual machine triggers initialization. This specification is given in Section 5.5 of the revised specification. As noted earlier, this description agrees with the specification of the events at the Java programming language level triggering initialization, given in Section 2.17.4 of the revised specification.

## Changes to Method Invocation

The following changes have been made to the specification of the method invocation instructions. Many of these are direct consequences of the changes described in the previous section; others are designed merely to clarify the presentation.

- Reliance on method tables, which was merely illustrative, has been removed.

The descriptions of the method invocation instructions made use of the well-known concept of a method dispatch table. The method tables were used as expository devices, but unfortunately many readers mistakenly thought that the use of such tables was a requirement of the specification. To clarify this point, a lookup algorithm is given instead.

- Link-time and runtime exceptions are used consistently.

The original specification sometimes listed exceptions that could be raised by an instruction according to their position in the exception hierarchy, rather than by when they might occur. This usage was inconsistent and sometimes erroneous.

The intent of the categories Linking Exceptions and Runtime Exceptions at the end of each instruction description is to describe at what phase of execution an error will be thrown. An important example of this is the treatment of `UnsatisfiedLinkError`. The descriptions of all method invocation instructions specify that `native` methods are bound at run time if they have not been bound already. If the binding fails, an `UnsatisfiedLinkError` is thrown. However, `UnsatisfiedLinkError` is consistently listed in the instruction descriptions of the original specification as a Linking Exception. To make it clear that the exception is actually thrown at run time, the revised specification lists `UnsatisfiedLinkError` as a Runtime Exception in the descriptions of all the method invocation instructions.

Another instance of this problem was in the description of the invokeinterface instruction. Most of the exceptions listed in the original specification of invokeinterface as Linking Exceptions actually occurred at run time. They are listed in the revised specification as Runtime Exceptions.

- It is possible to attempt to invoke `abstract` methods at run time.

This is a direct result of the elimination of the `abstract` method check during class or interface preparation, as discussed earlier. While in many cases the use of an `abstract` method on a class that is not `abstract` will still result in a link-time error, it is possible to construct cases where the error will not occur until run time.

Consider an `abstract` class A with `abstract` method `foo` and concrete subclass B. If B neglects to implement `foo`, then a method

              void bar(A a) {a.foo();}

will fail if invoked upon an instance of B. This will not be detected at link time, but at run time. As a result, invokeinterface and invokevirtual may raise an `AbstractMethodError` at run time.

- The invokeinterface instruction specification has changed.

The description of the invokeinterface instruction now states that the target of the method invocation must support the referenced interface. This is required by The JavaTM Language Specification and has been a property of all major Java virtual machine implementations for some time.

- The description of the invokespecial instruction has been clarified.

The second bullet on page 261 of the original specification was redundant and has been removed. The other bullets have been reordered, and the fact that ordinarily the resolved method is selected for execution has been asserted explicitly. These changes do not alter the specification in any way, but serve only to make the text more understandable.

## Nested Classes

Nested classes were introduced into the Java programming language after the original specification of the Java virtual machine and the first edition of The Java Language Specification were printed. The `Innerclasses` and `Synthetic` attributes, described in the revised specification in Section 4.7.5 and Section 4.7.6, respectively, were added in JDK release 1.1 in order to support nested classes.

Unfortunately, we have not been able to include a description of nested classes in the Java programming language overview given in Chapter 2. A complete description will be included in the next edition of the The JavaTM Language Specification. Until then, refer to the documentation on the World Wide Web at `http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses`.

## Chapter 9 of Original Specification Deleted

Chapter 9, "An Optimization," of the original specification documented an optimization technique used in Sun's contemporary Java virtual machine implementation. The original specification was clear that this chapter and the technique it described were not part of the Java virtual machine specification. However, the chapter provided an example of the flexibility that the Java virtual machine specification intends to give implementors. This information about Sun's implementation was also considered possibly useful to writers of tools such as debuggers.

The chapter has been removed from the revised specification. The optimization technique it described is now well understood. More important, the technique exactly as described is not used by many of the Java virtual machine implementations, including some of Sun's, developed since the original specification was published. The value of the chapter to tool writers has diminished for the same reason. Thus, the chapter is now best seen as documentation for a specific Java virtual machine implementation, making it inappropriate for the Java virtual machine specification.

## Other Issues

- In light of our experience with several releases of the Java platform, the interpretation of the version numbers defined as part of the `class` file format has changed. The major version number is now intended to correspond to new platform major releases (for instance, the Java 2 platform, Standard Edition, v1.2), while the minor version number may be used to represent release levels of platform implementations (for instance, the Java 2 SDK, Standard Edition, v1.2.1). Since the first public release of the Java platform, all `class` files have been generated using major version number 45 and minor version number 3. Hence, no existing well-formed `class` file is affected by this change in interpretation.

- Corresponding to the change in version number interpretation, the actual version numbers accepted by new implementations of the Java virtual machine have changed. Existing binaries are not affected by this change because these new virtual machine implementations will continue to accept `class` files with the historically used version numbers.

- It is now clear that reflective operations can cause class initialization. The original specification did not discuss the topic of reflection at all, since reflection did not yet exist in the Java programming language. Many subsequently added reflective operations correspond to language-level constructs that do require initialization and similarly must cause initialization. This is documented in the revised specification.

- Class finalization has been removed from the Java programming language and, consequently, from the revised specification as well. Class finalization had never been implemented, so the change had no effect on existing programs. The effects of class finalization are obtainable via instance finalization.

- The rules for class unloading have been clarified. The description of class unloading in the original specification gave, by way of illustration, certain necessary conditions for unloading a class. These conditions were misinterpreted as being sufficient conditions. This led to implementations that unloaded classes usable by a running program. The revised specification describes the precise circumstances under which classes may be unloaded.

- The instructions aastore, checkcast, and instanceof contain a subtyping algorithm. The original version of this algorithm was flawed in that it did not cover the case where two arrays whose component types were interfaces were being compared. The revised specification corrects this.

- The descriptions of the getfield and putfield instructions have been made less implementation specific. In particular, the revised specification eliminates the notion of particular field widths and offsets.

- The descriptions of the instructions putfield and putstatic now include a specification of their behavior when a field is `final`. This documents the behavior of existing implementations.

- The description of the process of throwing an exception in Section 3.10 has been made clearer and more precise.

- The descriptions of the various return instructions and athrow failed to note that these instructions could raise an `IllegalMonitorStateException`. The original specification implicitly allowed for the raising of such an exception as a consequence of Section 8.5:

An unlock operation by thread T on lock L may occur only if the number of preceding unlock operations by T on L is strictly less than the number of preceding lock operations by T on L.

and Section 8.13:

If execution of the method's body is ever completed, either normally or abruptly, an unlock operation is automatically performed on that same lock.

However, this had not been stated clearly and explicitly.

- Structured use of locks may now be enforced. The description of locking in `synchronized` statements given in Section 8.13 of the original specification was erroneous. It stated the following:

If execution of the body is ever completed, either normally or abruptly, an unlock operation is automatically performed on that same lock.

This is a property of programs written in the Java programming language, guaranteed by correct compilers for the Java programming language; it is not guaranteed by the Java virtual machine. However, programs do indeed make structured use of locking, and Java virtual machine implementations may rely on and enforce this property. The appropriate rules are given in the revised version of Section 8.13. As a consequence of those rules, `IllegalMonitorStateException` exceptions may be raised by the return instructions and athrow, and by the method invocation instructions when invoking `native` methods.

- The `Deprecated` attribute, an attribute introduced in JDK release 1.1 to support the `@deprecated` tag in documentation comments, has been specified. The presence of a `Deprecated` attribute does not alter the semantics of a class or interface.

Contents | Prev | Next | Index

The JavaTM Virtual Machine Specification
Copyright © 1999 Sun Microsystems, Inc. All rights reserved
Please send any comments or corrections to jvm@java.sun.com