In this lesson we unravel the terminology behind generics and look at some of the the strange syntax we get with it before delving deeper into generics in the following lessons.
Generics were added to the language in Java 5 and were the biggest changes made to the Java language in that release. Although generics are not just for collection types the majority of usage is within collections and so most of the examples in this section will use Collections.
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:
package info.java8; /* In the following code snippet we replace the formal type parameter E with an actual type parameter String */ List<String> aList = new ArrayList<String>();
<> (Diamond) Operator
The above code is quite verbose and can become difficult to read as shown in the following example which creates a generic map:
package info.java8; /* The following code is verbose and hard to read! */ Map<String, List<Map<String, Map<String, Integer>>>> map = new HashMap<String, List<Map<String, Map<String, Integer>>>>();
As you can see the above code is quite baffling and so the
<> (diamond) operator was introduced in Java 7 to deal with this.
<> operator adds type inference to the right hand side of an assignment when using generics and reduces verbosity.
Following is the above code using the
package info.java8; /* The following code uses the
<>operator */ Map<String, List<Map<String, Map<String, Integer>>>> map = new HashMap<>();
As you can see the above code uses the
<> operator on the right hand side of an assignment for type inference and is much easier to read!
So what do generics bring to the party? Even pre Java 5 we could create generalized interfaces, classes or methods by using references of the
So you will see a lot of generalized pre Java 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 Java 5 was released, made the decision to keep raw types in the language. For this reason generics are implemented through erasure (all generic code is removed at compile time) so legacy code can interoperate with generic code. This decision was made so that the billions of lines of code already written in Java were still compatible in Java 5. So wherever you see generic code in the language you can, although not in any way recommended, use raw types without any parameterisation instead.
Before we get into some coding now is a good time to look at the various terminology used in the rest of this section:
Generic terminology can be confusing at first but is fairly easy to understand once you grasp the basics.
When creating your own generic types it is best practice to use pneumonics for the formal type parameter rather than multiple letters.
- E pneumonic for element.
- K pneumonic for key
- T pneumonic for type
- V pneumonic for value
The table below lists various generic examples and the lessons in which each topic is discussed in detail.
|Raw Type||No parameterization.||Raw/Generic Type Comparison|
|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.
|Generic Interfaces||An interface followed by one or more formal type parameters delimitied by commas.||Generic Interfaces|
|Generic Classes||A class followed by one or more formal type parameters delimitied by commas.||Generic Classes|
|Bounded Type||Create a superclass boundary which all actual type parameters must be, or extend from.||Bounded Types|
|Unbounded Wildcard Type||Unknown type.||Unbounded Wildcard Types|
|Upper Bounded Wildcard Type||Create a superclass boundary which all unknown types must be, or subtypes thereof.||Bounded Wildcard Types|
|Lower Bounded Wildcard Type||Create a subclass boundary which all unknown types must be, or supertypes thereof.|
|Generic Methods||A method preceded by a generic.||Generic Methods|
|Generic Constructors||A constructor preceded by a generic.||Generic Constructors|
Lesson 1 Complete
In this lesson we looked at an overview generics and explained certain jargon surrounding generics.
In the next lesson we delve further into generics when we compare raw and generic types.