Well, that was explained in the trail.
In theory, when the Node class is compiled, its base type T is erased to Object .
Thus, in fact, it is compiled into something like
class Node { public Object data; public Node(Object data) {this.data = data; } public void setData(Object data) { System.out.println("Node.setData"); this.data = data; } }
Then you create a child class MyNode , which has its own setData(Integer data) . As for Java, this is an overload of the setData method, not its override. Each MyNode object has two setData methods. One of them is setData(Object) inherited from Node , and the other is setData(Integer) .
Basically, if you use a raw type, and you call setData with any reference that is not an Integer , the usual Java interpretation for this would be to overload setData(Object) .
This will not cause an assignment problem, because data declared as Object , not as Integer . The problem will only be when you try to return data to an Integer link. This simple Java behavior will cause the MyNode be "polluted" with inappropriate data.
However, as the trail says, the compiler adds a bridge method to make the child class look more like you intuitively think about it. It adds an override from setData(Object) to MyNode , so you cannot call the original, unsafe Node.setData(Object) . This bridge override method has an explicit conversion to Integer , which ensures that you cannot assign a non-integer link to data .
And this is the behavior that you see when you really compile and run the example.
If you run javap -p in the MyNode.class file, you will see that it has two setData methods:
class MyNode extends Node<java.lang.Integer> { public MyNode(java.lang.Integer); public void setData(java.lang.Integer); public void setData(java.lang.Object); }