Inner Classes Specification
Other changes in the Java 1.1 language
Note: This Inner Classes Specification is available for download as part of the JDK1.1 End Of Life (EOL) section of the Sun website. It has been included here because most of the specification is still relevant to the current Java classfile definition. However, the information has not been transferred into the latest Java Virtual Machine Specification or made available elsewhere in Sun's online Java resources.
The Java 1.1 language includes four additional extensions which fill small
holes in the language, and make certain kinds of APIs easier to use.
Instance initializers
The static initializer syntax is extended to support instance initialization also:
ClassBodyDeclaration:
Block
Initialization code introduced without the static keyword is executed by
every constructor, just after the superclass constructor is called, in textual order
along with any instance variable initializations.
An instance initializer may not return, nor throw a checked exception, unless
that exception is explicitly declared in the throws clause of each constructor.
An instance initializer in an anonymous class can throw any exceptions.
Instance initializers are useful when instance variables (including blank finals)
must be initialized by code which must catch exceptions, or perform other
kinds of control flow which cannot be expressed in a single initializer
expression. Instance initializers are required if an anonymous class is to
initialize itself, since an anonymous class cannot declare any constructors.
Anonymous array expressions
The array allocation syntax is extended to support initialization of the elements
of anonymous arrays. Just as a named array can be initialized by a brace-
enclosed list of element expressions, an array creation expression can now be
followed by such a brace-enclosed list. In both cases, the array type is not
allowed to include any dimension expressions; the dimension is computed by
counting the number of element expressions. Here is the new syntax:
ArrayCreationExpression:
new Type Dims ArrayInitializer
The equivalence of the following two statements illustrates the new syntax:
T v[] = {a};
T v[] = new T[] {a};
|
Class literals
PrimaryNoNewArray:
...
Type . class
void . class
A class literal is an expression consisting of the name of a class, interface, array,
or primitive type followed by a `.' and the token class. It evaluates to an
object of type Class, the class object for the named type (or for void).
For reference types, a class literal is equivalent to a call to Class.forName
with the appropriate string, except that it does not raise any checked
exceptions. (Its efficiency is likely to be comparable to that of a field access,
rather than a method call.) The class literal of a reference type can raise
NoClassDefFoundError, in much the same way that a class variable
reference can raise that error if the variable's class is not available.
The class literal of a primitive type or void is equivalent to a static variable
reference to a pre-installed primitive type descriptor, according to this table:
boolean.class == Boolean.TYPE
char.class == Character.TYPE
byte.class == Byte.TYPE
short.class == Short.TYPE
int.class == Integer.TYPE
long.class == Long.TYPE
float.class == Float.TYPE
double.class == Double.TYPE
void.class == Void.TYPE
|
Java APIs which require class objects as method arguments are much easier to
use when the class literal syntax is available. Note that the compiler is
responsible for taking into account the ambient package and import
statements when processing the TypeName of a class literal.
The older usage of Class.forName requires the programmer to figure out the
desired package prefix and write it in a class name string. The difficulty of
getting the string spelled right becomes greater in the presence of inner classes,
since their names (as processed by Class.forName) are encoded with `$'
characters instead of dots.
Note that a class literal never contains an expression, only a type name.
Blank finals and final local variables
A blank final is final variable declaration (of any kind) which lacks an
initializer. A blank final must be assigned an initial value, at most once.
The definite assignment rules are extended to record variables which are
"definitely unassigned," and an assignment to a blank final is prohibited
unless the final is definitely unassigned before the assignment statement.
Subsequently, it is definitely assigned, and, being a final, it cannot be re-
assigned along the same execution path.
The definite unassignment rules take into account back-branches of loops, so
that a variable occurrence in a loop body may not be definitely unassigned if
the loop makes an assignment which can reach the occurrence via a back-
branch. The definite assignment checks work as if the first iteration of the loop
had been unrolled into an if statement.
A blank final class variable must be definitely assigned by a static initializer
(in the same class). This is the only context where class variables are checked
for definite assignment.
A blank final instance variable must be definitely assigned by a non-static
initializer, or else by every constructor. These are the only contexts in which
definite assignment checking is done on instance variables. Within these
contexts, an assignment to this.V is recognized as performing an assignment
to the name V for purposes of definite assignment checking.
Local variables and parameters of all sorts can now be declared final:
LocalVariableDeclaration:
ModifiersOpt Type VariableDeclarators
FormalParameter:
ModifiersOpt Type VariableDeclaratorId
Such a variable is subject to the usual definite assignment rules governing local
variables. In addition, it cannot be assigned to, except for initialization.
A method parameter or catch formal parameter may be declared final. This
has no effect on the method signature or the caught exception type. Within the
body of the method or catch, the parameter may not be assigned to.
The final declaration modifier may be used to make local variables and
parameters available to inner classes.
|