New Features in Java 5
Several useful syntactic elements were introduced in Java 5. All these features are supported by an
updated compiler, and all translate to already defined Java bytecode, meaning that virtual machines can
execute these features with no need for an update:
❑ Generics: A way to make classes type-safe that are written to work on any arbitrary object type,
such as narrowing an instance of a collection to hold a specific object type and eliminating the
need to cast objects when taking an object out of the collection.
❑ Enhanced for loop: Acleaner and less error-prone version of the for loop for use with iterators.
❑ Variable arguments: Support for passing an arbitrary number of parameters to a method.
❑ Boxing/unboxing: Direct language support for automatic conversion between primitive types
and their reference types (such as int and Integer).
❑ Type-safe enumerations: Clean syntax for defining and using enumerations, supported at the
language level.
❑ Static import: Ability to access static members from a class without need to qualify them with a
class name.
❑ Metadata: Coupled with new tools developed by third-party companies, saves developers the
effort of writing boilerplate code by automatically generating the code.
These features update the Java language to include many constructs developers are used to in other languages.They make writing Java code easier, cleaner, and faster. Even if you choose not to take advantage
of these features, familiarity with them is vital to read and maintain code written by other developers.
Generics
Java 5 introduced generics, also known as parameterized types. Generics allow you to write a class that
can operate on any type but that specific type is not specified until declaration of an instance of the class.
Because this type is not specified as part of the class definition, the class becomes generic, gaining the
ability to work on any type specified. The most obvious example, and a great use of generics, is the collection classes. The ArrayList class, for example, was written to hold, simply, Object. This means
objects lose their type when added to the ArrayList and a cast is needed when accessing an element
of the ArrayList. However, code that uses a generic version of the ArrayList can say “I want this
ArrayList to hold only Strings.” This adds additional type-safety to Java because, if anything other
than a String is added to the collection, the compiler will catch it. This also means that a cast is no
longer needed when accessing elements—the compiler knows it only holds Strings and will produce
an error if the elements are treated as anything other than a String. Specifying String as the parameterized
type is as easy as placing the type in angle brackets:
ArrayList<String> listOfStrings; // <TYPE_NAME> is new to the syntax
String stringObject;
listOfStrings = new ArrayList<String>(); // <TYPE_NAME> is new to the syntax
listOfStrings.add(new String(“Test string”)); // Can only pass in String objects
stringObject = listOfStrings.get(0); // no cast required
Generics are also known as parameterized types where a type is the parameter. As can be seen in the previous example, String is the formal type parameter. This same parameterized type must be used when
instantiating the parameterized type.
Because one of the goals of the new language features in Java 5 was to not change the Java instruction
set, generics are, basically, syntactic sugar. When accessing elements of the ArrayList, the compiler
automatically inserts the casts that you now don’t have to write. It’s also possible to use the primitive
data types as a parameterized type, but realize that these incur boxing/unboxing costs because they are
implicitly converted to and from Object. Nonetheless, there are benefits in increased type-safety and
increased program readability.
Using Generics
It is straightforward to create objects of a generic type. Any parameters must match the bounds specified.
Although you might expect to create an array of a generic type, this is only possible with the wildcard
type parameter. It is also possible to create a method that works on generic types.
Let's see usage scenarios:-
Class Instances
Creating an object of a generic class consists of specifying types for each parameter and supplying any
necessary arguments to the constructor. The conditions for any bounds on type variables must be met.
Note that only reference types are valid as parameters when creating an instance of a generic class.
Trying to use a primitive data type causes the compiler to issue an unexpected type error.
This is a simple creation of a HashMap that assigns Floats to Strings:
HashMap<String,Float> hm = new HashMap<String,Float>();
updated compiler, and all translate to already defined Java bytecode, meaning that virtual machines can
execute these features with no need for an update:
❑ Generics: A way to make classes type-safe that are written to work on any arbitrary object type,
such as narrowing an instance of a collection to hold a specific object type and eliminating the
need to cast objects when taking an object out of the collection.
❑ Enhanced for loop: Acleaner and less error-prone version of the for loop for use with iterators.
❑ Variable arguments: Support for passing an arbitrary number of parameters to a method.
❑ Boxing/unboxing: Direct language support for automatic conversion between primitive types
and their reference types (such as int and Integer).
❑ Type-safe enumerations: Clean syntax for defining and using enumerations, supported at the
language level.
❑ Static import: Ability to access static members from a class without need to qualify them with a
class name.
❑ Metadata: Coupled with new tools developed by third-party companies, saves developers the
effort of writing boilerplate code by automatically generating the code.
These features update the Java language to include many constructs developers are used to in other languages.They make writing Java code easier, cleaner, and faster. Even if you choose not to take advantage
of these features, familiarity with them is vital to read and maintain code written by other developers.
Generics
Java 5 introduced generics, also known as parameterized types. Generics allow you to write a class that
can operate on any type but that specific type is not specified until declaration of an instance of the class.
Because this type is not specified as part of the class definition, the class becomes generic, gaining the
ability to work on any type specified. The most obvious example, and a great use of generics, is the collection classes. The ArrayList class, for example, was written to hold, simply, Object. This means
objects lose their type when added to the ArrayList and a cast is needed when accessing an element
of the ArrayList. However, code that uses a generic version of the ArrayList can say “I want this
ArrayList to hold only Strings.” This adds additional type-safety to Java because, if anything other
than a String is added to the collection, the compiler will catch it. This also means that a cast is no
longer needed when accessing elements—the compiler knows it only holds Strings and will produce
an error if the elements are treated as anything other than a String. Specifying String as the parameterized
type is as easy as placing the type in angle brackets:
ArrayList<String> listOfStrings; // <TYPE_NAME> is new to the syntax
String stringObject;
listOfStrings = new ArrayList<String>(); // <TYPE_NAME> is new to the syntax
listOfStrings.add(new String(“Test string”)); // Can only pass in String objects
stringObject = listOfStrings.get(0); // no cast required
Generics are also known as parameterized types where a type is the parameter. As can be seen in the previous example, String is the formal type parameter. This same parameterized type must be used when
instantiating the parameterized type.
Because one of the goals of the new language features in Java 5 was to not change the Java instruction
set, generics are, basically, syntactic sugar. When accessing elements of the ArrayList, the compiler
automatically inserts the casts that you now don’t have to write. It’s also possible to use the primitive
data types as a parameterized type, but realize that these incur boxing/unboxing costs because they are
implicitly converted to and from Object. Nonetheless, there are benefits in increased type-safety and
increased program readability.
Using Generics
It is straightforward to create objects of a generic type. Any parameters must match the bounds specified.
Although you might expect to create an array of a generic type, this is only possible with the wildcard
type parameter. It is also possible to create a method that works on generic types.
Let's see usage scenarios:-
Class Instances
Creating an object of a generic class consists of specifying types for each parameter and supplying any
necessary arguments to the constructor. The conditions for any bounds on type variables must be met.
Note that only reference types are valid as parameters when creating an instance of a generic class.
Trying to use a primitive data type causes the compiler to issue an unexpected type error.
This is a simple creation of a HashMap that assigns Floats to Strings:
HashMap<String,Float> hm = new HashMap<String,Float>();