Sign in Get started
WRIT E FOR US CODING INT ERVIEW COURS E →
You have 2 free stories left this month. Sign up and get an extra one for free.
How to use Generics in Java
A complete guide to Java Generics
Manusha Chethiyawardhana Follow
May 21 · 5 min read
Photo by Alex Iby on Unsplash
Generics is a key concept in Java. Most Java codebases will make use of
them. So, it’s inevitable that a developer will run into them at some point.
That’s why it’s essential to understand them correctly. Understanding
generics properly will help you ace your Java interview as well.
In this article, I’m going to discuss what generics are, how to use them in
Java, and what their advantages are.
. . .
Generics were added in Java 5 to provide compile-time type checking
and to eliminate the risk of ClassCastException that was common when
working with collection classes. Collection classes in Java are used to
store and manipulate groups of objects. For example, the ArrayList
collection class can store any type of object. Because it was designed as a
container for Java’s base class type Object. Thus an ArrayList object can
hold a String or Integer or any Java type. There was no way to create an
ArrayList of only Strings or Integers before Generics. With Generics, we
can define the type of object that the ArrayList can hold. Thus allowing to
create a single object type ArrayLists.
1 import java.util.ArrayList;
2 public class GenEx1{
3 public static void main(String []args){
4 ArrayList<String> al = new ArrayList<String>();
5 al.add("Name");
6 al.add("Age");
7 al.add(22); // Compile Error!
8 }
9 }
GenEx1.java hosted with ❤ by GitHub view raw
As you can see in the example above, the generic type is defined by the
use of angled brackets. And in the example, only String objects can be
stored inside the ArrayList. Collection classes in Java have generic types
now. Now let’s see how to write our own generic classes, interfaces, and
methods.
. . .
Generic Classes
In the generic class declarations, the name of the class is followed by the
type parameter section. We can follow the same syntax to create generic
interfaces. The type parameter, also known as the type variable, is an
identifier used to specify a generic type name. The type parameter
section of the generic class can include one or more type parameters
that are separated by commas. These classes are also known as
parameterized classes.
1 class Test<K, V>{
2 private K key;
3 private V value;
4
5 Test(K key, V value){
6 this.key = key;
7 this.value = value;
8 }
9
10 public K getKey(){
11 return key;
12 }
13 public V getValue(){
14 return value;
15 }
16
17 }
18 public class GenEx2{
19 public static void main(String []args){
20 Test<String,Integer> pair1 = new Test<String,Integer>("ID",223);
21 Test<String,Integer> pair2 = new Test<String,Integer>("Age",22);
22 System.out.println(pair1.getKey() + "=" + pair1.getValue() );
23 System.out.println(pair2.getKey() + "=" + pair2.getValue() );
24 }
25 }
GenEx2.java hosted with ❤ by GitHub view raw
In the above example, the Test class has two type parameters named as
K and V. So an object of Test class can store two different types of
values.
. . .
Generic Methods
If we could write a single sort method to sort the elements in an Integer
array, a String array, or an array of any type that supports ordering, that
would be great, right? Java Generic methods allow us to specify a set of
related types, with a single method declaration. You’ll be able to write a
single generic method declaration that can be called with arguments of
different types. The type parameter section must be specified before the
method return type. A type parameter can also be used as the return
type of the method.
1 public class GenEx3{
2
3 public static < E > void printArray( E[] inputArray ) {
4 for(E element : inputArray) {
5 System.out.print(element +" ");
6 }
7 System.out.println();
8 }
9
10 public static void main(String args[]){
11 Integer[] intArray = { 1, 2, 3, 4, 5 };
12 Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
13 Character[] charArray = { 'P', 'I', 'Z', 'Z', 'A' };
14
15 System.out.print("integerArray contains: ");
16 printArray(intArray);
17 System.out.print("doubleArray contains: ");
18 printArray(doubleArray);
19 System.out.print("characterArray contains: ");
20 printArray(charArray);
21 }
22 }
GenEx3.java hosted with ❤ by GitHub view raw
In the above example, the printArray method can be used to print
elements of any type of array.
. . .
Bounded Type Parameters in Generics
So far, we’ve only seen unbounded generic type arguments. Unbounded
means that our generic type arguments could be any type that we want.
There may be times when you want to restrict the types that are allowed
to be passed to the type parameter. For example, a method that operates
on numbers may only want to accept instances of the Number class or its
subclasses. Bounded type parameters are used for this. To declare a
bounded type parameter, list the type parameter’s name, followed by the
extends keyword, followed by its upper bound.
1 public abstract class Cage<T extends Animal> {
2 abstract void addAnimal(T animal)
3 }
4
5 class Animal{}
6 class Dog extends Animal{}
7 class Cat extends Animal{}
GenEx4.java hosted with ❤ by GitHub view raw
In the example, the generic type of Cage class must always be a subclass
of Animal or the Animal class. So, we can pass either Cat, Dog, or Animal
class as generic type arguments.
If needed, we can also declare multiple bounds for our generic types. So
the abstract class in the above example can be modified as shown below.
public abstract class Cage<T extends Animal & Comparable<T>>
Here, the type parameter must now respect both the Animal class and
the Comparable interface.
. . .
Wildcards and Subtyping in Generics
The question mark(?) is the wildcard in generics and represents an
unknown type. If we want our generic method to be working with all
types, in this case, an unbounded wildcard can be used. An unbounded
wildcard is represented by <?> . We can also use bound wildcards. There
are two types of bounded wild cards, the upper bounded wildcard, and
the lower bounded wildcard.
Upper bounded wildcards are used to relax the restriction on the type of
variable in a method. For example, let’s say we don’t know whether a list
is going to be a type of Number, Integer, or Double. So how are we going
to get the sum of the elements in that list? We can use the upper bounded
wildcard to solve this. The example below shows how to implement it.
1 public void method( List<? extends Number> list){
2 double sum = 0;
3 for(Number i : list){
4 sum += i.doubleValue();
5 }
6 System.out.println(sum);
7 }
GenEx5.java hosted with ❤ by GitHub view raw
Lower bounded wildcards are used to increase the restriction on the type
of variable in a method. Suppose we want to add only Integers to a list,
whereas we also want to accept a list of supertypes of Integer. We can
use a lower bound wildcard to achieve this. From the example below, we
can see how to use it.
1 public void addIntegers(List<? super Integer> list){
2 list.add(new Integer(10));
3 list.add(new Integer(20));
4 }
GenEx6.java hosted with ❤ by GitHub view raw
Although Integer is a subtype of Number in Java, List<Integer> is NOT a
subtype of List<Number> . The common parent of them is List<?> . So
subtyping in generic classes is done with wildcards. The example below
will help you to understand this.
1 ArrayList<? extends Integer> intList = new ArrayList<>();
2 ArrayList<? extends Number> numList = intList; // OK
3
4 ArrayList<Integer> intList2 = new ArrayList<>();
5 ArrayList<Number> numList2 = intList2; // Compile Error!
GenEx7.java hosted with ❤ by GitHub view raw
. . .
Diamond Operator (<>)
The diamond operator, also known as the diamond syntax, was
introduced as a new feature in Java 7. The purpose of the diamond
operator is to simplify the use of generics when creating an object.
ArrayList<String> al = new ArrayList<>();
By using the diamond operator, we can simplify the declaration of the
String ArrayList as shown above.
. . .
Advantages of Generics
Now that you know how to use Generics, you must be thinking about why
we need to use them. Well, there are three main reasons why we use
them,
1. Type safety
2. Typecasting is not required
3. Reusable Code
Generics ensure compile-time safety, which allows you to catch the
invalid types while compiling the code. So, you don’t need to worry about
run time exceptions. Not requiring individual typecasting is another
advantage of using generics. You define the initial type and then let the
code do the casting for you. We can also avoid code duplication. Without
generics, we have to copy and paste the same code but for different
types. With generics, we do not have to do this.
. . .
That’s all for this article. I hope you guys have learned what Java
generics are and how to use them, and hope to bring you more Java
knowledge in the future.
Thank you so much for reading and happy coding!
. . .
References
Oracle Java documentation on generics
Java Generics Interview Questions
Java Technology Programming Coding Software Development
432 claps
WRIT T EN BY
Manusha Chethiyawardhana Follow
faculty and Taekwondo player
Level Up Coding Follow
Coding tutorials and news. The developer homepage
gitconnected.com
Write the rst response
More From Medium
5 JavaScript T ips I How To Become A True 7 T hings to Build When To My Programmer Self
Learned From Vue Keyboard Warrior (And You Feel Bored as a 20 Years Ago: Do T hese
Source Code Stop Using Your Mouse) Programmer 4 T hings More
bit sh in Level Up Coding keypressingmonkey in Level Daan in Level Up Coding Alvin Lee in Level Up Coding
Up Coding
React Antipatterns to T he Easiest Way to RxJS Terms You MUST Simple Vue Directives
Avoid Host a Multi-page know in Angular T hat’ll Save You T ime
John Au-Yeung in Level Up Dashboard using T RAN SON HOANG in Level Up John Au-Yeung in Level Up
Coding Python, Dash, and Linux Coding Coding
for Beginners
Eric Kleppen in Level Up
Coding
Discover Medium Make Medium yours Become a member
Welcome to a place where words matter. On Follow all the topics you care about, and we’ll Get unlimited access to the best stories on
Medium, smart voices and original ideas take deliver the best stories for you to your Medium — and support writers while you’re at it.
center stage - with no ads in sight. Watch homepage and inbox. Explore Just $5/month. Upgrade
About Help Legal