Migrating to 1.1 |
Inner Classes
Probably the single most significant change to the Java language for JDK 1.1 is the ability to define classes as members of other classes. Such classes are called inner classes and are covered in [PENDING: link to inner classes]Anonymous Classes
When you are writing simple subclasses or implementations of interfaces, creating a bunch of classes for each trivial class can be awkward. Anonymous classes are a convenient short form of inner classes that have no name, only an implementation that is specified right along with thenew
.For a brief discussion of anonymous classes and an example that uses one, refer to [PENDING: link to inner classes].
Instance Initializers
In JDK 1.0.2, the Java language supportedstatic
initializers that let you initialize class variables.JDK 1.1 adds a similar syntax for performing instance initialization:class ClassWithStaticInitializer { static { // ... initialization code ... } }Initialization code introduced without theclass ClassWithInstanceInitializer { { // ... initialization code ... } }static
keyword is executed by every constructor, just after the superclass constructor is called, in the same order that they appear in the source code, 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.
[PENDING: link to new material that talks about this in the book]
Array Initialization
You can initialize the contents of an array when younew
it. For example, the following would be a flexible way to create an array of strings:
The array allocation syntax is extended to support initialization of the elements of anonymous arrays.String[] tutorialTeam = new String[] { "Alison", "Kathy", "Mary" };Class literals
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.
' and the tokenclass
. It evaluates to an object of typeClass
, 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 raiseNoClassDefFoundError
, 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.TYPENew Uses for final
Method parameters and local variables can be declaredfinal
. If you do not expect to change the value of a parameter or variable inside the method, you can declare itfinal
to let the compiler enforce that. The compiler can also optimize uses of afinal
parameter or variable since it knows the value will never change.The
final
-ness of a parameter is not part of the method signature-it is simply a detail of the implementation. A subclass can override a method and add or drop anyfinal
parameter modifiers you wish. You can also add or dropfinal
modifiers in a method's parameters without causing any harm to existing compiled code that uses that method. Thefinal
declaration does not show up in the documentation generated from doc comments.You can defer initialization of a
final
field or variable, as long as you initialize it before it is used and assign a value to it exactly once. The compiler will check for proper assignment, as will the verifier before code is executed. Deferred initialization can be useful when the proper value can only be calculated by a loop or other code that is hard or impossible to encode in a variable initializer, such as code that throws exceptions that must be caught and handled.Transient Defined in 1.1
Thetransient
keyword, has defined meaning for 1.1 (whereas it was undefined in 1.0.2. In 1.1,transient
is used to mark member variables that should not be saved during object serialization.
Migrating to 1.1 |