package practice;
class Node<T> {
T data;
public Node(T data) { this.data = data; }
public void setData(T data) {
System.out.println("Node.setData");
this.data = data;
}
}
class MyNode extends Node<Integer> {
public MyNode(Integer data) { super(data); }
@Override
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
public class Practice {
public static void main(String[] s)
{
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello"); // Causes a ClassCastException to be thrown.
Integer x = mn.data;
}
}
Why does this code throw exception at n.setData("Hello"); when actually it should throw the exception at Integer x = mn.data;?
http://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html
I think there is a small mistake in the tutorial: they should have said that the error is thrown at line
n.setData("Hello");That’s because when you call
n.setData("Hello");you call the bridge method:n.setData(Object object)onMyNodeclass, otherwise you would have a compile time error.But the bridge method looks like this:
You see that the bridge tries to invoke the
setData(Integer anInt)with a cast on thedata. And this cast fails because you provided aString.What’s also interesting at this example is that you get no compile time error when using
@Overrideannotation even that you technically don’t override, but the compiler overrides later. The annotation is very very useful here to inform that thesetData(Object object)will be called onMyNodenot onNode. This explains why you don’t see any of theSystem.outmessages.