Java Generics Tutorial- Methods and Functions of Generics in Java

Get Job-ready: Java Course with 45+ Real-time Projects! - Learn Java

Before we get into Java Generics as a topic, imagine yourself in the following situation.

You are a music fanatic. You love listening to music. However, you do not listen to only one particular type of music alone.

You listen to all kinds of music depending on your mood. Be it classical, rap you listen to everything.

However, the catch is, you can only play a particular genre in a particular application. This means that you can only play rock on App 1 and classical music on App 2.

Now you have to keep all the different applications on your phone at the same time or have to download individual applications each time you change your genre. Sounds rough, right? Of course, it is.

That is exactly why we have only one music application where we can play any genre we want.

Java Generics have a similar application.

What is Java Generics?

Generics, as the name suggests, is a general way of defining methods, definitions, and collections so that they are not dependent on the data type supplied to them.

They can function the same no matter what datatype they use.

Collections such as ArrayLists use generics extensively. Generics are generally declared in the “<>” brackets.

If this is the first time you are observing java Generics then you would still be confused. Let us clear it up with an example now shall we?

Java example to illustrate the use of Java Generics:

package com.dataflair.javagenerics;
import java.io.*;
import java.util.*;


class GenericClass<T>
{
    //This is a generic class definition. The type is T as mentioned. 

    GenericClass()
    {
        System.out.println("The generic class is declared now. You can use it well");
    }

    public void methodgeneric(T obj)
    {
        System.out.println("The type of the object that this class now contains is "+obj.getClass().getSimpleName());
    }
}
public class GenericsExample {
    public static void main(String[] args) {
        
        GenericClass<Integer> test=new GenericClass<>();
        Integer a=5;
        test.methodgeneric(a);

        //Now we use the same class but with a different datatype. 
        
        GenericClass<String> teststring = new GenericClass<>();
        String s="DataFlair is the best";
        teststring.methodgeneric(s);
    }    
}

Output:

The generic class is declared now. You can use it well
The type of the object that this class now contains is Integer
The generic class is declared now. You can use it well
The type of the object that this class now contains is String

If you observe carefully we set the value of the same class with different datatypes. That is the power of generics.

It allows you to work with different datatypes without worrying about the repercussions and different rules of different data types.

Now let us see what the program is doing step by step.

  1. As soon as the main function calls the generic type object the constructor gets called and you can see the line “The generic class is declared now. You can use it well”
  2. Now, as the class is generic in nature, it allows the Integer type object passed to its methods and prints the class name.
  3. You can easily identify the class name and the type of the variable passed to the method by the .getClass() method. Simple!
  4. Now we pass a different datatype but thanks to generics the method behaves the same way!
  5. This is the magic of generics in Java.

Why is the use of Generics in Java?

  1. This is a big one, you save redundancy! Similar to the example we talked about in the beginning, it is evident that you do not need to write different classes for the same functionality again and again!
  2. Generics allow you to see compile-time errors. Without generics, the compiler may sometimes allow illegal assignments to a collection. But if you explicitly specify what kind of data a collection should be having with generics, then it will throw a compile-time error if you do an illegal assignment.
  3. You don’t need to explicitly typecast each and every variable. Using generics the autoboxing and unboxing does it for you.
  4. Generics also enforce type-safety in Java.
  5. You can implement generic algorithms with the help of Generics in Java.

Java Generic Methods

You do not always need to use generic classes when you are unsure of the datatype of a class.

You can simply go and declare a method with generics too. How? Let us see an example. Nothing teaches us stuff better than examples right?

Let us dive in!

Rules to declare Generic Methods in Java

There are a few rules that we have to adhere to when we need to declare generic methods in Java. Let us look at some of them.

  1. You should explicitly specify type parameters before the actual name of the return type of the method. The type parameter is delimited by angle brackets. Example: <T>
  2. You should also include the type parameters in the declaration of the program and separate them with commas. A type parameter specifies a generic type name in the method.
  3. All the type parameters are only useful when they have to declare reference types. Remember that the type parameters cannot denote primitive data types such as int, float, String etc.
  4. The type parameters come in handy when the programmer has to specify the return type of the variables. Note that the parameters are also generic. The type parameters are also useful for denoting the type of the variables in the function parameters. These are actual type parameters.

Java program to understand how we can declare generic methods in Java:

package com.dataflair.javagenerics;

public class GenericMethod {

    public <T> void methodgen(T var1)
    {
        System.out.println("The value passed is of type "+var1.getClass().getSimpleName());

    }
    public static void main(String[] args) {
        
        GenericMethod ob = new GenericMethod();
        ob.<String>methodgen("DataFlair is the best");

        //Sometimes we can omit the explicit mention of the type in <> and the compiler can automatically identify the type. 

        ob.methodgen("Learning Java at DataFlair");
        ob.methodgen(154);
    }
}

Output:

The value passed is of type String
The value passed is of type String
The value passed is of type Integer

Type Parameters in Java

There are a few naming conventions we need to know when we use Java Generics. Let us have a look at them.

  • T – This represents Type.
  • E – This parameter represents Elements.
  • K – This parameter represents Keys.
  • N – This represents Numbers.
  • V – This represents Values.

Bounded Types

When you want to specify a particular type which is a subclass of a particular class you can use Bounded Types. Bounded types allow you to restrict the data type of the collection. For example, if you write a generic with the extends keyword then you can use bounded types.
Eg <T extends A>

If A is Number class then you can use all types of data which are of type Integer, Float, Double, etc.

Java program to illustrate bounded types in Java:

package com.dataflair.javagenerics;
class GenericTypeClass<T extends Number>
{
    //This is a class where you can only use generic objects of classes
    //which are a subclass of Number that is Integer, Float etc. 
    GenericTypeClass(T obj)
    {
        System.out.println(obj.getClass().getName());
        
    }
}


public class Simple{
public static void main(String[]args)
    {
    Integer a = 10;
    GenericTypeClass<Integer> obj = new GenericTypeClass<>(a);
    String s="DataFlair";
    //GenericTypeClass<String> obj2=new GenericTypeClass<>(a);

    
     }
}

Output:

java.lang.Integer

If you try to remove the commented line the compiler will throw an error because the String class does not extend the Number class.

Wildcard In Java

The question mark is of great importance in Java. This ? mark is a Wildcard in Java.

Wildcards are useful for determining the bounded type of generic classes or methods. How? Let us see what we mean.

The wildcards can be:

  • Type parameters
  • return types
  • local variables
  • fields

However, you should not use generics for:

  • type argument for generic method invocation.
  • supertype
  • generic class invocation

Summary

In this article, we learned about Java generics and how they are useful in programming.

They generalize the functioning of the collection and allow the programmer to focus on the application rather than the intricacies of datatype.

Did you like our efforts? If Yes, please give DataFlair 5 Stars on Google

courses

DataFlair Team

DataFlair Team creates expert-level guides on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. Our goal is to empower learners with easy-to-understand content. Explore our resources for career growth and practical learning.

1 Response

  1. chris says:

    can you exaplain all the keywords used along with the java default class name like ?

Leave a Reply

Your email address will not be published. Required fields are marked *