Introduction
Sun Microsystem's release of Java 1.5 included many
new features to the programming language, and its libraries. This
document highlights the new features which are of most importance.
The target audience is experienced Java programmers
who wish to quickly review the features introduced in Java 5.
All the example Java source files can be downloaded
in a zip archive here.
Version Number
The version can be confusiong at first. Once installed,
typing "java -verion" at the command prompt results in the utility
reporting a version of 1.5..... And yet it is also referred to
as version 5, or J2SE 5, and less often as Tiger.
Autoboxing and Unboxing
The Java interpreter can automatically encapsulate
a Java primitive type into its equivalent type wrapper class, and
vice versa.
Primitive Type |
Java Wrapper |
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Char |
boolean |
Boolean |
Example class
(the full source is available here):
package com.j3ltd.java15changes;
public class Autoboxing { public static void main(String[] args) {
Integer intObject = 100;
Integer intObject2 = 200;
intObject ++;
switch (intObject) {
case 101: intObject2 = intObject + intObject2;
break;
}
System.out.println("intObject is " + intObject + " intObject2 is " + intObject2);
}
}
When the above class is run the console output is:
intObject is 101 intObject2 is 301
Enumeration Types
- An enum is a special type of class.
- It is
a type for which all its possible values are known.
- An enum
cannot extend or be extended.
- Constructors and methods can be defined in an enum
- An enum can be used in a switch statement
- Two special static methods are automatically generated:
- public static E[] values() returns an array of the constants
in the declaration order.
- public static E valueOf(String name) returns the enum constant
with the name given as the parameter.
- An enum implicitly extends java.lang.Enum
- A variable of an enum type does not need the new keyword
Example enum (the full source is available here):
enum Vehicle { unicycle(1), bicycle(2), motorbike(2), car(4), van(4), truck(6), lorry(8); int numberOfWheels; Vehicle(int wheels) { numberOfWheels = wheels; } public int getWheelNumberOfWheels() { return numberOfWheels; } }
The enum can be used as follows:
Vehicle aVehicle; aVehicle = Vehicle.van; if (aVehicle == Vehicle.van) { System.out.println("Do you drive a your van in the UK?\n"); }
Generics
Generics allows a classes, interfaces and methods
to have the type of data they use as a parameter. The Java collections
framwork has been revamped to make use of this. Previously, for
example, an ArrayList stored its members as the Object type. with
Generics an ArrayList of "Integer" is possible.
A simple generic
class declaration looks like this (the fuill source of the generics
examples is available here):
class GenericEg1<G> {
G genericMember;
GenericEg1(G param) {
genericMember = param;
}
G getMe() {
return genericMember;
}
}
To use the above class, a variable can be decalred and used as follows,
note the autoboxing is also used here.
GenericEg1<Integer> value;
value = new GenericEg1<Integer>(100);
int itIs = value.getMe();
A generic type can have more than one type parameter:
class GenericExample<A, B, C>
Bounded types allow the type parameter(s) to be limited to a superclass:
class GenericEg2<A extends Number>
Wildcard type arguments can be used to state that a parameter to a method
can be of any type. It is also possible to use bounding on wildcard
arguments. For example (in the GenericEg2 example class):
public double sum(List<? extends Number> list) { double toReturn = 0.0; for (Number number : list) { toReturn += number.doubleValue(); } return toReturn; }
In the above example, The method sum can take any list which contains
Number or subtypes of Number, such as Integer. Without the '?'
argument, the List must be Number.
Note: it is also possible to use the super keyword
instead of extends. In such a case, the list could
only be of Number or its supertypes (only Object in this case),
not subtypes such as Integer.
Enhanced For Statement
The syntax of the enhanced for statement is as
follows:
for (Type loop-variable : set-expression) statement
- The set-expression must either be an array or implement
the java.lang.Iterable.
- The loop-variable is a local variable of a valid type for the set's
contents.
Example (the full source is the same as the generics example, available
here):
public double sum(List<? extends Number> list) {
double toReturn = 0.0;
for (Number number : list) {
toReturn += number.doubleValue();
}
return toReturn;
}
Annotations
Annotations allow some information to be
attached to a package, class, interface, enum, field, method...
One annotation Java programmers should be familiar with is the
"@Deprecated" annotation, which signifies that the declaration
should not be used anymore: it has been replaced by a newer version.
Another very active area for annotations is the EJB (Enterprise
Java Beans) specification. In this case annotations are used to
simplify the EJB developper's task by allowing EJB classes and
methods to be identified as being of particular interest to the
EJB container.
As an applications programmer, annotations
are used but very rarely defined. Programming tool suppliers,
and to some extent those in charge of the Java specification,
are more likely to specify the annotations the rest of us will
use.
A brief overview of defining, and using,
annotations is given here, so that the reader gains a "working
knowledge" of annotations.
Example (the full source is available here) :
The following annotation is defined:
enum ReleaseType {alpha, beta, production };
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@interface ClassVersion {
String author() default "unknown";
int majorVersion() default 1;
int minorVersion() default 0;
ReleaseType release() default ReleaseType.alpha;
}
Notes:
- An enum defines the different release types for Java code: alpha,
beta, production.
- An annotation called ClassVersion is defined with the following
characteristics:
- The Retention is RUNTIME. So it can be queried at runtime, other
values are SOURCE or CLASS
- The target is TYPE and ANNOTATION_TYPE, hence this annotation
can only be applied to other types (class, interface, enum)
or other annotations.
-
The annotation has various members that are used to attach version information.
At runtime, the class version annotation can be queried as follows:
@ClassVersion(author = "Fred", release = ReleaseType.production) public class AnnotationExample {
public static void main(String[] args) {
AnnotationExample eg = new AnnotationExample();
ClassVersion version = eg.getClass().getAnnotation(ClassVersion.class);
System.out.println("AnnotationExample by " + version.author() +
" Version " + version.majorVersion() + '.' +
version.minorVersion() + ' ' + version.release() + " release");
}
}
When run, the following is output:
AnnotationExample by Fred Version 1.0 production
release
Annotations do not always take parameters, sometimes they don't take
any (for example the @Deprecated annotation).
Miscellaneous
Java 5 also has a few minor additions, which are
worth mentioning. C and C++ programmers should not have any difficulty
in recogninzing some of these new features. However, it is worth
pointing out that there are slight differences, so if all else
fails, it is worth reading up the finer details.
Varargs: Methods can be defined
to take variable length arguments that is to say zero or more,
depending on how the method is defined.
Formatted I/O: C/C++ programmers
are accustomed to the printf() method. Java 5 has added the Formatter class
in the java.util package. Also the java.io.PrintStream and java.io.PrintWriter
classes have the printf() varargs method.
Static import: it is possible
to import the static members (variable and methods) from another
class. This may reduce readability though. For example, instead
of coding "System.out.println()", "out.println()" could be written
instead, if java.lang.System.* is imported as a static import.
The example below shows the new features just mentioned
(the full source is available here):
import static java.lang.System.*;
public class Miscellaneous {
static void print(Object...objects) {
for (Object o : objects) {
out.print(o);
}
}
public static void main(String[] args) {
// System.out.* imported as a static import
out.printf("Demonstration of the new printf method %d\n", 10);
print("demonstration of a varargs ", "method ",
"call ", 10, " \n");
}
}
When the above is run, the output produced is as
shown below:
Demonstration of the new printf method 10
demonstration of a varargs method call 10
Serializable: Implementation of
the java.io.Serializable interface are strongly recommended to
define a
" private static final long serialVersionUID". If one is not defined, java
tries to generate one for the Serializable class. This is used by Java to decide
whether two different class files are equivalent (using the class name and serialVersionUID.
Hence the version number should be renewed when the class is changed in a way
that would make it incompatible with previous versions.
The method used to generate the serialVersionUID
can be manual, or using one of the tools provided in the JDK,
called serialver, the file is located in the jdk's bin folder.
.
|