Angle Bracket <> in Java with Examples Different types of Recursions in Java Java Lambda Filter Example Java Program for Shopping Bill Pythagorean Triplet with Given Sum Using Single Loop in Java TemporalAdjusters lastInMonth() method in Java with Examples ZIP API in Java Atomic reference in Java Digit Extraction in Java DRY (Don't Repeat Yourself) Principles in Java with Examples Empty array in Java Is main method compulsory in Java? Java I/O Operation - Wrapper Class vs Primitive Class Variables Java Program to Find the Perimeter of a Rectangle Java Thread Priority Java Type Erasure Need of Concurrent Collections in Java Nested ArrayList in Java Print Odd and Even Numbers by Two Threads in Java Square pattern in Java TemporalAdjusters next() method in Java with Examples What does start() function do in multithreading in Java Convert Number to Words Problem in Java Detect And Remove Cycle in a Single Linked List in Java Evolution of Interfaces in Java How to pad a String in Java Implementing Patricia Trie in Java Java Program to Find the Most Repeated Word in a Text File java.util.UUID class in Java ReadWriteLock Interface in Java Reference Data Types in Java Sort An Array According to The Count of Set Bits in Java Alternate Vowel and Consonant string in Java Built-in Exceptions in Java with Examples Capture the Pawns Problem in Java Collections.shuffle() Method in Java with Examples JDBC MySQL Localhost 3306 Alternate Vowel and Consonant string in Java Built-in Exceptions in Java with Examples Capture the Pawns Problem in Java Collections.shuffle() Method in Java with Examples Convert Number to Words Problem in Java Detect And Remove Cycle in a Single Linked List in Java Evolution of Interfaces in Java How to pad a String in Java Implementing Patricia Trie in Java Java Program to Find the Most Repeated Word in a Text File java.util.UUID class in Java ReadWriteLock Interface in Java Reference Data Types in Java Sort An Array According to The Count of Set Bits in Java JDBC MySQL Localhost 3306 Adding a Character as Thousands Separator to Given Number in Java Circular Primes in Java Equilibrium Index Problem in Java Java String regionMatches() Method with Examples LFU Cache Problem in Java Longest Repeating and Non-Overlapping Substring in Java Prefix Suffix Search in Java Product Array Puzzle Problem in Java Russian Doll Envelopes Problem in Java Second Most Repeated Word in a Sequence in Java Special Two-Digit Numbers in a Binary Search Tree in Java Swap Corner Words and Reverse Middle Characters in Java Toggle K bits Problem in Java Upside Down Binary Tree in Java Verbal Arithmetic Puzzle Problem in Java Insert a String into another String in Java Print Shortest Path to Print a String on Screen in Java Search Insert Position in Java BST Sequences in Java Burrows - Wheeler Data Transform Algorithm in Java Convert BST to Min Heap in Java Fibonacci Sum in Java Get name of current method being executed in Java

Java Type Erasure

In Java, the principle of Generics was first introduced to render tighter checks at the compile time itself and enable Generic programming. Type erasure applies higher-level type constraint checks at the compile term and ignores or discards the element type data at the run time. In Type erasure, the compiler ensures that no additional classes are created, and there is no runtime overhead.

For implementing the generics, the Java compiler will apply the type erasure to the following.

  • Substitute every type parameter in the generic types with their bounds or the objects if the type parameters are unbounded. It means that if we have a type parameter that is not bounded, then it will be substituted with the object at the time of program compilation.

The produced byte code only consists of the ordinary class, method and interface.

  • Add type casting if needed to maintain type safety.
  • Produce the bridge methods that maintain the principle of polymorphism in the generic types that are extended when the type parameters are not bounded.

Working

In general, the generic code that is compiled makes use of the Java.lang.Object every time we talk about E (it can also be any other parameter) - and some data (metadata) informs the Java compiler that it is a generic type. When you compile any code against the generic type or method, the compiler automatically interprets what the programmer is trying to convey( i.e., the Java compiler identifies the type argument of E) and checks at the compile time if the programmer is following the rules. On the other hand, the code emitted again tries to talk in terms of Java.lang.object - the compiler generates the additional casts where required. During the execution, the List and a List are the same; the Java compiler has removed the additional type.

// Here, the type parameter E is unbounded

public class GenericsType<E> 

{

// Here, E gets substituted with the default, 

// which is the Object

E object;

// constructor of the class

GenericsType(E obj)

{

object = obj;

}

// retrieves the object

E getObject()

{

return object;

}

}

In the above code, the type parameter E is unbounded, due to which, after compilation, the Java compiler substitutes it with the Object. Hence, the compiled class won't consist of any type parameter. It is shown in the below code.

// Here, E gets bounded by the Object (Java.lang.Object)

public class GenericsType 

{

// Here, E gets substituted with the default, 

// that is the Object

Object object;

// constructor of the class

GenericsType (Object obj)

{

object = obj;

}

// retries the object

Object getObject()

{

return object;

}

}

Now, go through another example given below. Here, the type parameter E extends the Java.lang.String class.

public class GenericsType1 <E extends String>  

{

// Here, E gets substituted with the String 

// that is the Object

E e;

// constructor of the class

GenericsType1(E obj)

{

e = obj;

}

// retrieves the object

Object getObject()

{

return e;

}

}

After the compilation, the type parameter E gets substituted with the String, which is the object shown in the code below.

// Here, E gets bounded by the Object (Java.lang.String)

public class GenericsType1 

{

// Here, E gets substituted with the String 

// that is the Object

String e;

// constructor of the class

GenericsType1 (String obj)

{

e = obj;

}

// retrieves the object

Object getObject()

{

return e;

}

}

Example 1

Let us go through an example where we have implemented Type erasure in Java.

FileName: TypeErasure.java

// Java program to demonstrate TypeErasure

import java.util.*;

public class TypeErasure {   

// main method

public static void main(String[] args) {

// Creates a list of Strings

List<String> sports = new ArrayList<>();

// Add elements to the list

sports.add("cricket");

sports.add("football");

sports.add("hockey");

sports.add("tennis");

Iterator<String> iterator = sports.iterator();

// Iterates over the elements from the list

while (iterator.hasNext()) {

String s = iterator.next();

System.out.println(s);

}

}

}

Output:

cricket

football

hockey

tennis

Explanation: In the above example, no warnings will be thrown after compilation as we have used the Type Erasure feature in our program.

Example 2

Please go through the example below where we have not used TypeErasure.

FileName: TypeErasure1.java

// Java program to demonstrate TypeErasure

import java.util.*;

public class TypeErasure1 {

// Constructor

public TypeErasure1 () {

}

// main method

public static void main(String[] args) {

// Creates a list of Strings

List sports = new ArrayList();

// Add elements to the list

sports.add("cricket");

sports.add("football");

sports.add("hockey");

sports.add("tennis");

String str;

for (Iterator itr = sports.iterator(); itr.hasNext();

System.out.println(str))

str = (String)itr.next();

}

}

Output:

cricket

football

hockey

tennis

Explanation: It is necessary to specify the list type in the code to validate it at the compile time and show no warnings at the run time. In the above example, a few warnings will be shown after compilation since we are not using Type Erasure in the program. Note that the output of the above example will not change, and only the warning will be shown in the console window.

Raw use of parameterized class 'List'

Raw use of parameterized class 'ArrayList'

Unchecked call to 'add(E)' as a member of raw type 'java.util.List'

Raw use of parameterized class 'Iterator'

Benefits of Type Erasure--------

  • It provides type safety.
  • It offers backward compatibility.
  • It helps avoid Runtime overhead.
  • Only one version of code is produced for all the generic instances, due to which a minimal amount of time is spent in the JIT (Just in Time) compiler, and lesser RAM is consumed for storing the produced code.
  • Improves the performance as the generic type information is removed from the byte code, reducing produced bytecode size and leading to faster execution.
  • There is no need to change the bytecode.