![]() |
VOOZH | about |
Generics in Java refer to parameterized types that allow writing code which works with multiple data types using a single class, interface, or method. They improve reusability and ensure type safety at compile time.
A generic class is a class that can operate on objects of different types using a type parameter. Like C++, we use <> to specify parameter types in generic class creation. To create objects of a generic class, we use the following syntax:
// To create an instance of generic class
BaseType <Type> obj = new BaseType <Type>()
15 GeeksForGeeks
Note: In Parameter type, we can not use primitives like "int", "char" or "double". Use wrapper classes like Integer, Character, etc.
In a generic class, the type parameter T behaves like a normal data type within the class. Once a specific type is provided while creating an object, the compiler replaces T with that type.
This means T can be used just like a regular type for:
We can also pass multiple Type parameters in Generic classes.
GfG 15
We can also write generic methods that can be called with different types of arguments based on the type of arguments passed to the generic method. The compiler handles each method.
java.lang.Integer = 11 java.lang.String = GeeksForGeeks java.lang.Double = 1.0
When we declare an instance of a generic type, the type argument passed to the type parameter must be a reference type. We cannot use primitive data types like int, char.
Test<int> obj = new Test<int>(20);
The above line results in a compile-time error that can be resolved using type wrappers to encapsulate a primitive type. But primitive type arrays can be passed to the type parameter because arrays are reference types.
// Using diamond operator (<>), Java infers the type automatically
ArrayList<int[]> a = new ArrayList<>();
Generic types differ based on their type arguments, but this difference exists only at compile time. During compilation, Java removes generic type information through a process called type erasure, replacing type parameters with their bounds or Object. As a result, generics ensure type safety at compile time while maintaining backward compatibility at runtime.
Output:
error:
incompatible types:
Test cannot be converted to Test Explanation: At compile time, Test<Integer> and Test<String> are treated as different parameterized types.
Java generics enforce type safety during compilation, so assigning one to another results in a compile-time error.
However, due to type erasure, the generic type information is removed at runtime and both become the raw type Test.
Even though they are the same raw type at runtime, the compiler prevents the assignment to maintain type safety.
3
Explanation: Even though we created objects of Test<Integer>, Test<String> and Test<Double>, only one class Test exists at runtime due to type erasure. Therefore, the static variable count is shared among all instances, regardless of their type parameter.
The type parameters naming conventions are important to learn generics thoroughly. The common type parameters are as follows:
Programs that use Generics has got many benefits over non-generic code.
1. Code Reuse: We can write a method/class/interface once and use it for any type we want.
2. Type Safety: Generics make errors to appear compile time than at run time (It's always better to know problems in your code at compile time rather than making your code fail at run time).
Suppose you want to create an ArrayList that store name of students and if by mistake the programmer adds an integer object instead of a string, the compiler allows it. But, when we retrieve this data from ArrayList, it causes problems at runtime.
Example: Without Generics
Output :
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
at Test.main(Test.java:19)Here, we get runtime error.
Why This Happens (Type Safety Issue)
How Generics Solve This Problem:
Example: With Generics
Output:
15: error: no suitable method found for add(int)
al.add(10);
^3. Individual Type Casting is not needed: Generics remove the need for manual type casting during retrieval, making code cleaner and safer.
4.Generics Promotes Code Reusability: Generics enable writing a single reusable method that works with multiple data types.
Example: Generic Sorting
Sorted Integer array: 6, 22, 41, 50, 58, 100, Sorted Character array: a, c, d, g, t, v, x, Sorted String array: Amiya, Gudly, Kandhei, Kuna, Mama, Rani, Sweta,
Here, we have created a generics method. This same method can be used to perform operations on integer data, string data and so on.
Note: If you are new to Java, start practicing Generics with basic examples like generic Box, generic Pair and generic methods.