Sun Java Solaris Communities My SDN Account Join SDN
 
The Java Language Specification

Clarifications and Amendments to the JLS, Second Edition

 
The Java Language Specification, Third Edition, revises the Second Edition as a result of generics (JSR 14), metadata (JSR 175), language additions (JSR 201), the assert statement (JSR 41 from Java 2 SDK 1.4), the revised memory model (JSR 133), and Unicode supplementary character support (JSR 204).
 
A Maintenance Review of the Second Edition covered additional minor corrections and adjustments, including clarifications to:
  • floating point literals
  • String operators
  • private class members
  • asserts in initialization
  • handling the $ character in class names
  • local class declarations
  • the distinction between exception handling of expressions and statements
  • caveats to interface type members
 
Download Maintenance Review: Java Language Specification, Third Edition
(2.1MB zip file containing 18 PDF chapters; all revisions are marked by change bars relative to the Second Edition)  
 

 
 

Older Clarifications and Amendments to the JLS, Second Edition

 

Asserts (JSR-41)

The final specification is here . We expect to provide detailed JLS changes in the near future.

JLS 3.7

The production for EndOfLineComment should read:

// CharactersInLineopt

In other words, the requirement for a LineTerminator is dropped. This requirement was not implemented by the great majority of compilers, and serves no purpose.

JLS 4.5.4

At the end of this section, the following paragraph should be appended:

We call a variable that is final, of primitive type or type String, and initialized with a compile-time constant expression (§15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1) and binary compatibility (§13.1, §13.4.8).

This is part of a series of amendments necessary to ensure uniform treatment of compile time constants in the specification, in a manner that is consistent with longstanding practice. The affected sections are: 4.5.4. 12.4.1, 13.1, 13.4.8, 15.28.

JLS 6.4.3

The third bullet of this section should read:

If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.   It is a compile time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

The final sentence (given here in bold)  is new, and explicitly calls attention to an error condition.

JLS 11.2

The last two paragraphs of section 11.2 on page 221 should be amended to read. This resolves an apparent discrepancy with JLS 8.6 :

Static initializers (§8.7), class variable initializers, and instance variable initializers within named classes and interfaces (§8.3.2), must not result in a checked exception; if one does, a compile-time error occurs. No such restriction applies to instance initializers or instance variable initializers within anonymous classes (§15.9.5).
An instance initializer of a named class may not throw a checked exception unless that exception or one of its superclasses is explicitly declared in the throws clause of each constructor of its class and the class has at least one explicitly declared constructor. An instance initializer in an anonymous class (§15.9.5) can throw any exceptions.

JLS 12.4.1

The bullet at the top of page 237 should read:
  • A static field declared by T is used and the field is not a constant variable (§4.5.4).
This is part of a series of amendments necessary to ensure uniform treatment of compile time constants in the specification, in a manner that is consistent with longstanding practice. The affected sections are: 4.5.4. 12.4.1, 13.1, 13.4.8, 15.28.

JLS 13.1

The text  of the paragraph at the bottom of page 253 and the top of page 254 should be amended to read:

The reference to f must be compiled into a symbolic reference to the qualifying type of the reference, plus the simple name of the field, f. 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 constant variables (§4.5.4)  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.


This is part of a series of amendments necessary to ensure uniform treatment of compile time constants in the specification, in a manner that is consistent with longstanding practice. The affected sections are: 4.5.4. 12.4.1, 13.1, 13.4.8, 15.28.

JLS 13.4.8

The last paragraph of page 264 should be amended to read;

If a field is a constant variable (§4.5.4), then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for the usage of the field unless they are recompiled. This is true even if the usage itself is not a compile-time constant expression (§15.28) .

This is part of a series of amendments necessary to ensure uniform treatment of compile time constants in the specification, in a manner that is consistent with longstanding practice. The affected sections are: 4.5.4. 12.4.1, 13.1, 13.4.8, 15.28.

JLS 14.10

The example of "Duff's device" on page 290 should be amended to read:

int q = (n+7)/8;
switch (n%8) {
case 0:            do {        foo();                // Great C hack, Tom,
case 7:                    foo();                // but it’s not valid here.
case 6:                    foo();
case 5:                    foo();
case 4:                    foo();
case 3:                    foo();
case 2:                    foo();
case 1:                    foo();
            } while (--q > 0);
}


Operator Precedence

Operator precedence is implicitly defined by the grammar in chapter 15. Thus there is no need for a table giving the precedence explicitly.

JLS 15.12.2.2

If more than one method declaration is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.

The precise definition is as follows. Let m be a name and suppose that there are two member  methods named m, each having n parameters. Suppose that the types of the parameters of one member method are T1, . . . , Tn; suppose moreover that the types of the parameters of the other method are U1, . . . , Un. Then the first member method is more specific than other  if and only if  Tj can be converted to Uj by method invocation conversion, for all j from 1 to n. A method is strictly more specific  than another if and only if it is both more specific and the signatures of the two methods are not identical.

A method is said to be maximally specific for a method invocation if it is applicable and accessible and there is no other applicable and accessible method that is strictly more specific.

If there is exactly one maximally specific method, then it is in fact the most specific method; it is necessarily more specific than any other method that is applicable and accessible. It is then subjected to some further compile-time checks as described in §15.12.3.

It is possible that no method is the most specific, because there are two or more maximally specific methods. In this case:

If all the maximally specific methods have the same signature, then:

  • If one of the maximally specific methods is not declared abstract, it is the most specific method.
  • Otherwise, all the maximally specific methods are necessarily declared abstract. The most specific method is chosen arbitrarily among the maximally specific methods. However, the most specific method is considered to throw a checked exception if and only if that exception is declared in the throws clauses of each of the maximally specific methods. 
  • Otherwise, we say that the method invocation is ambiguous, and a compile-time error occurs.

JLS 15.28

The first two lines of this section should be amended to read:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

Note that this implies that 1/0 is not a compile time constant. Such an expression , if evaluated,
throws an appropriate exception at runtime.

An additional bullet should be added to the list of bullets on pages 405-406:
  • Parenthesized expressions whose contained expression is a constant expression.
In addition, the last two bullets on page 406 are amended to read:
  • Simple names that refer to constant variables (§4.5.4)
  • Qualified names of the form TypeName . Identifier that refer to constant variables (§4.5.4)
This is part of a series of amendments necessary to ensure uniform treatment of compile time constants in the specification, in a manner that is consistent with longstanding practice. The affected sections are: 4.5.4. 12.4.1, 13.1, 13.4.8, 15.28.

Typographical errors

Addison-Wesley title page (the 2nd title page in the book)
        Edtition -> Edition
------------------------------------------------------------------------
p. xix, 7 lines from bottom:
        simultannously -> simultaneously
------------------------------------------------------------------------
p. 167, middle of page:
        Identifer -> Identifier
------------------------------------------------------------------------
p. 175,  second text line
        has an instance variable contents -> has an instance variable boxContents
------------------------------------------------------------------------
p. 215, 3 lines from bottom:
        In Java programming language -> In the Java programming language
------------------------------------------------------------------------
p. 252, 12 lines from bottom:
        Java platform beyond -> Java platform is beyond
------------------------------------------------------------------------
p. 329, line 1:
        denotes a value, that is -> denotes a value that is
------------------------------------------------------------------------
p. 343, 2 lines before last code example:
        is available in, -> is available,
------------------------------------------------------------------------
p. 430, middle of page:
        threads working memory -> thread's working memory
------------------------------------------------------------------------
p. 439, 6 lines from bottom:
        perform an use -> perform a use
------------------------------------------------------------------------