There is potential for a minor performance loss, because the compiler sometimes adds synthetic bridge methods. Consider the following example:
public class GenericPerformance {
public static void main(final String[] args) {
final Stuff<Integer> stuff = new IntStuff();
final Integer data = stuff.getData();
stuff.putData(data);
}
}
interface Stuff<T> {
T getData();
void putData(T stuff);
}
class IntStuff implements Stuff<Integer> {
private Integer stuff;
public Integer getData() {
return stuff;
}
public void putData(final Integer stuff) {
this.stuff = stuff;
}
}
If you look at the generated bytecode, you will see: In the main method, the erased interface methods
java.lang.Object Stuff.getData()
void Stuff.putData(java.lang.Object)
are invoked. That methods, implemented in IntStuff
with the signatures
java.lang.Object getData()
void putData(java.lang.Object)
both with the modifiers public bridge synthetic
, delegate to the "real" methods
java.lang.Integer IntStuff.getData()
void putData(java.lang.Integer)
The first synthetic method merely returns the Integer result, while the second performs a cast from Object to Integer before calling putData(Integer)
.
If you change the stuff
variable to type IntStuff
, then both Integer
methods are called instead of the synthetic Object
methods.