Java泛型擦除效果及桥方法的探讨

/**
 * most of the example code is quoted from
 * {@link http://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html}
 * 
 * 此用例说明
 * 1.java的泛型擦除效果
 * 2.java编译器为了在泛型中实现多态而专门增长“桥方法”
 * 
 * @author wenziheng
 *
 */
public class TestErasure {

    @Test
    public void testBridgeMethod(){
        MyNode mn = new MyNode(5);
        Node n = mn;                // A raw type - compiler throws an unchecked warning
        try{
            n.setData("Hello");     // Causes a ClassCastException to be thrown.
        }catch(ClassCastException cce){
            Assert.assertTrue(cce instanceof ClassCastException);
        }
        Integer x = mn.data;
        Assert.assertTrue(5 == x);
    }
}

class Node<T> {

    public 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); 
    }
    
    // 桥方法是编译器为了解决擦除后泛型不能实现多态而添加的
    // 有了桥方法,就能让泛型也有多态。感受上就是先调用setData(Object data)而后转换到setData(Integer data)
    // 因此,ClassCastException也会发生在这里
    //
    // public void setData(Object data) {
    //    setData((Integer) data);
    // }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
    
}

//
//通过擦除,编译器没有添加桥方法前, Node 和   MyNode:
//
//public 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;
//    }
//}
//
//public class MyNode extends Node {
//
//    public MyNode(Integer data) { super(data); }
//
//    public void setData(Integer data) {
//        System.out.println("MyNode.setData");
//        super.setData(data);
//    }
//}
相关文章
相关标签/搜索