Consider an example:
public interface Shape<T extends Shape<T>> {
T getType();
void setType(T type);
}
public class Circle implements Shape<Circle> {
Circle getType() { }
void setType(Circle circle) { }
}
It looks good as of now. But, after type erasure, the interface loose it's generic type, and the type T
is replaced with the upper bound. So the interface and class looks like:
public interface Shape {
Shape getType();
void setType(Shape type);
}
public class Circle implements Shape {
Circle getType() { }
void setType(Circle circle) { }
}
Now, here's the problem. The method in Circle
after erasure is not really an overridden version of Shape
. Note that, now the methods as it looks, applies greater restriction on the parameter it takes, and the value it returns. This is because the erasure changes the signature of method in interface.
To solve this issue, the compiler adds bridge method for those, which delegates the call to those actual methods in class.
So, the class is really converted to:
public class Circle implements Shape {
Circle getType() { }
void setType(Circle circle) { }
// Bridge method added by compiler.
Shape getType() { return getType(); } // delegate to actual method
void setType(Shape shape) { setType((Circle)shape); } // delegate to actual method
}
So, the bridge method is now the overridden version of the methods in the interface, and they delegate the call to the actual method that does the task.
Note that the type used in the bridge method is the erasure of the type parameter of the interface, in this case Shape
.
References:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…