6.3-6.4 Generic Types
Generics were introduced with Java5 and in this lesson we look at the reasons for doing this. We then look at usage of type parameters in class/interface declarations, instance variables, method arguments, and return types. We finish the lesson by looking at generic methods as well as methods that make use of wildcard types.
Lets take a look at the points outlined at the Oracle Website for this part of the certification.
- Section 6: Collections / Generics
- Write code that uses the generic versions of the Collections API, in particular, the Set, List, and Map interfaces and implementation classes. Recognize the limitations of the non-generic Collections
API and how to refactor code to use the generic versions.
- Develop code that makes proper use of type parameters in class/interface declarations, instance variables, method arguments, and return types; and write generic methods or methods that make use of wildcard types and understand the similarities and differences between these two approaches.
- Write code that uses the generic versions of the Collections API, in particular, the Set, List, and Map interfaces and implementation classes. Recognize the limitations of the non-generic Collections API and how to refactor code to use the generic versions.
When we talk about generics or a generic type what we are actually talking about is a parameterized type. So a class, interface or method that has has one or more generic types in
its definition can be thought of as generic and we can replace the generic type with a parameterized type. When we define the actual interface, class or method within our code we replace
the formal type parameter with the actual type parameter required. As an example we saw in the Collection Hierarchy Diagram that the List
interface is specified as
List<E>. The following code shows a declaration of an
ArrayList<E> using a polymorphic declaration that will
only except String objects:
/* In the following code snippet we replace the formal type parameter E with an actual type parameter String */ List<String> aList = new ArrayList<String>();
So what do generics bring to the party? Even pre 1.5 we could create generalized interfaces, classes or methods by using references of the
So you will see a lot of generalized pre 1.5 stuff that works on
Object but this approach could not guarantee type safety. The problem being that you
need to cast from
Object to the actual type being worked on.
For instance every time you wanted to read from a collection you would need to cast every object you read. If an object of the wrong type was inserted into the collection then the cast could cause a runtime exception. The exception might be in a program completely removed from the collection itself and might not happen for a long time, making every collection a possible ticking timebomb. The exception to this were Array objects where we have always implicitly declared the type on array creation, so arrays have always been type safe.
With generic type declarations of collections the compiler knows that only objects of the specified type can be added to this collection or throws up a compiler error. Through this mechanism we can achieve type safety for our collections and not have to worry about someone else inputting an invalid object into our collections.
Because of the huge impact generics had on the language the developers at Sun microsystems, the original writers of Java and still in control when 1.5 was released, made the decision to keep raw types in the language. This decision was made so that the billions of lines of code already written in Java were still compatible in Java5. So wherever you see generic code in the language you can, although not in any way recommended, use raw types without any parameterisation instead.
|Raw Type||No parameterization.|
|Generic Type||An interface, class or method followed by one or more formal type parameters within angled brackets.|
|Formal Type parameter||One or more formal type parameters delimitied by commas, which can be thought of as placeholders for the actual type parameters.|
|Parameterized Type||An interface, class or method followed by one or more actual type parameters within angled brackets.|
|Actual Type parameter||One or more actual type parameters delimitied by commas. Object types are allowed when using generics but primitive types are not.|
|Bounded Type||Create a superclass boundary which all actual type parameters must be or extend from.|
|Unbounded Wildcard Types||Unknown type.|
|Bounded Wildcard Types||Create a superclass boundary which all unknown types must be or extend from.|
Click a link in the table above to see usage for the generic type.