Sometimes to support type-erasure use case of generics, Java compiler creates a synthetic method, which is called a bridge method, as part of the type erasure process.
What is type erasure?
Type Erasure is a process, where Java Compiler replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.
Box.java
public class Box<T> {
private T data;
public Box(T data) {
this.data = data;
}
public T getData() { return data; }
}
In the above example, "T" is unbounded type. So Java Compiler replaces Every Occurrence of T with Object.
public class Box {
private Object data;
public Box(Object data) {
this.data = data;
}
public Object getData() { return data; }
}
Consider one more Example
public class Box<T extends Integer> {
private T data;
public Box(T data) {
this.data = data;
}
public T getData() { return data; }
}
After type Erasure, Type Parameter “T” is replaced with Integer.
public class Box{
private Integer data;
public Box(Integer data) {
this.data = data;
}
public Integer getData() { return data; }
}
Bridge method
Sometimes to support type-erasure use case of generics, Java compiler creates a synthetic method, which is called a bridge method, as part of the type erasure process.
Let me explain it with an example.
Container.java
package com.sample.app;
public class Container<T> {
public T data;
public Container(T data) {
this.data = data;
}
public void setData(T data) {
this.data = data;
}
}
IntegerContainer.java
package com.sample.app;
public class IntegerContainer extends Container<Integer> {
public IntegerContainer(Integer data) {
super(data);
}
public void setData(Integer data) {
super.setData(data);
}
}
Consider the following code.
IntegerContainer integerContainer = new IntegerContainer(5);
// A raw type - compiler throws an unchecked warning
Container container = integerContainer;
// Below statement throws a ClassCastException
container.setData("Hello");
Integer x = integerContainer.data;
After type erasure, this code becomes like below.
IntegerContainer integerContainer = new IntegerContainer(5);
Container container = (Container)integerContainer;
container.setData("Hello");
Integer x = (String)integerContainer.data;
As I said previously, in some situations, as part of type erasure process, Java compiler creates a synthetic method called bridge method.
After type erasure, the method signatures do not match; the Container.setData(T) method becomes Container.setData(Object). As a result, the IntegerContainer.setData(Integer) method does not override the Container.setData(Object) method.
To solve this problem and preserve the polymorphism of generic types after type erasure, the Java compiler generates a bridge method to ensure that subtyping works as expected.When you decompile the class file ‘IntegerContainer.class’, it contains below code snippet.
$javap -c com/sample/app/IntegerContainer.class
Compiled from "IntegerContainer.java"
public class com.sample.app.IntegerContainer extends com.sample.app.Container<java.lang.Integer> {
public com.sample.app.IntegerContainer(java.lang.Integer);
Code:
0: aload_0
1: aload_1
2: invokespecial #1 // Method com/sample/app/Container."<init>":(Ljava/lang/Object;)V
5: return
public void setData(java.lang.Integer);
Code:
0: aload_0
1: aload_1
2: invokespecial #2 // Method com/sample/app/Container.setData:(Ljava/lang/Object;)V
5: return
public void setData(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #3 // class java/lang/Integer
5: invokevirtual #4 // Method setData:(Ljava/lang/Integer;)V
8: return
}
As you see above snippet, you can confirm that compiler generates a synthetic (bridge) method ‘public void setData(java.lang.Object);’,
The bridge method IntegerContainer.setData(object) delegates to the original IntegerContainer.setData(Integer) method. As a result, the container.setData("Hello"); statement calls the method IntegerContainer.setData(Object), and a ClassCastException is thrown because "Hello" can't be cast to Integer.
You may like
Understanding ConcurrentModificationException in Java
No comments:
Post a Comment