Generics are a Java programming construct that allow you to use types as parameters when you define classes, methods, and interfaces. This provides a way for you to re-use the same code with different inputs.
There are several benefits to using generics:
- Catching errors at compile time instead of runtime: The Java compiler applies strong type checking to generics and will throw errors if there are any type safety violations. It is much easier to fix compile-time errors than runtime errors.
- To quote the book, Head First Java, “With generics, you can create type-safe collections where more problems are caught at compile-time. Without generics, the compiler would happily let you put a Pumpkin into an ArrayList that was supposed to hold only Cat objects.”
- Generic Algorithms: Using generics, you can create algorithms that operate on collections that contain different types. This provides the benefits of code re-use and readability.
- Elimination of Casts: Prior to the implementation of generics in Java, classes placed in arrays would be stored and retrieved as Objects. This would mean that you could, for example, place a Dog instance into an array, but you would have to typecast it back from Object to Dog. As mentioned earlier, this created the potential for runtime errors, because the array would not be type-checking for Cat instances being stored.
This code snippet without generics requires casting:
This code snippet, rewritten to use generics, does not require casting:
This also adds type safety by preventing illegal objects from being stored in the array:
Most of the time, the code you will write that deals with generics will be collection-related code. The way that you will use generics will be primarily in one of three ways:
Creating instances of generified classes:
Understanding the Documentation
The Java convention is to use “E” (for “element”) as the stand-in for the type of element a collection class should accept.
So, when implementing ArrayList
In generics, “extends” means “extends” OR “implements.”
Normally, in Java, “extends” refers to class inheritance, where “implements” refers to interfaces. When dealing with generics, however, “extends” refers to both of these. Interfaces and classes are treated the same way.
Sure, the Java engineers probably could have used a new keyword, like “is,” or something. But generally, whenever there is a chance to re-use an existing keyword, it is best to do that in order to lessen the risk of breaking existing code.