What is Generics in Java?

Java Generics is just like templates in C++. The main idea of java generics is to reducing the bugs and adding an extra layer of abstraction over types means to allow the type (Integer, String, … etc and user pre-defined types) to be a parameter to methods, classes, and interfaces.

Why need Generics?

Let’s suppose a scenario where we want to create just a list in Java to store Integer; we can be tempted to write:

List list = new LinkedList();
list.add(new Integer(1)); 
Integer i = list.iterator().next();

Surprisingly, the compiler will start complaining about the last line. It mainly doesn’t know what data type is returned. The compiler will only require an explicit casting just like below :

Integer i = (Integer) list.iterator.next();

Basically, there is no contract that could guarantee that the return only type of the list is an Integer. And the defined list could hold any object. We only just know that we are retrieving a list by inspecting the context.

When we are looking at types, it can only guarantee that it is an Object, thus requires an explicit cast to ensure that the type is safe.

This cast can be annoying as we know that the data type in this list is an Integer. The cast is also cluttering our program code.

It can create an issue of the type-related runtime errors also if a programmer makes a mistake with the explicit casting.

It would be much easier if the programmers could express their intention of using specific types and the compiler can ensure the correctness of such type. And this is the core idea behind the generics in java.

Let’s modify the first line of the previous code snippet which we writing above to:

List<Integer> list = new LinkedList<>();

By adding this diamond operator  <> containing the type, we basically narrow the specialization of this list only to Integer type means we only specify the type that will be held inside the list is an Integer.

The compiler easily enforce the type at compile time.

Mainly, in small programs, this might be like a trivial addition, however, in larger programs, this can add significant robustness experience and makes the program easier to read.

Methods in Generics 

The Generics methods in java are those methods that are written with a single method declaration and can be called with arguments of different types. The compiler will easily ensure the correctness of whichever type is used. Below are some properties of generic methods:

  • The Generics methods in java have a type parameter just like a diamond operator enclosing the type before the return type of the method declaration.
  • The type of parameters can be bounded.
  • The Generics methods in java have so many different type parameters separated by commas in the method signature.
  • The method body for a generic method is just like a simple method

What is the Bounded Generics?

Bounded means “restricted“, we can restrict types that can be accepted by a method in generics in java. For example, we can specify that a method that accepts a type and all its subclasses (upper bound) or a type all its superclasses (lower bound). To declare an upper-bounded type which we can use the keyword extends after the type followed by the upper bound that we want to use. Just like below:

public <T extends Number> List<T> fromArrayToList(T[] a) {
    ...
}

The keyword used here to mean that the type T extends the upper bound in case of a class or implements an upper bound in case of an interface.

Conclusion

The Generics in java is a powerful addition to the Java language as it makes the programmer’s job easier and less error-prone. It mainly enforces the type of correctness at compile time and, most importantly, enables implementing generic algorithms without causing any extra overhead to our applications.