Java的Generics和c++的Template到底有什么不同?
先了解Java的Generics:
根据Java的文档,Java引入Generics一是为了在编译时提供更强的类型检查,二是为了泛型编程。
编译时,Java靠type erasure来实现Generics:
1. 将所有的泛型参数替换为限定(bound这里如何翻译?)的类型,如果没有限定,就替换为Object类。因此然生的字节码和普通的类文件一样;
2. 为了保证类型安全,必要的时候会是使用cast;
3. 为了维护继承的泛型类型之间的多态的正确性,必要的时候会生成bridge methods。
考虑下面的泛型类,这个类代表单链表的节点。(一下例子均出自java doc)
public class Node<T> { private T data; private Node<T> next; public Node(T data, Node<T> next) } this.data = data; this.next = next; } public T getData() { return data; } // ...}
public class Node { private Object data; private Node next; public Node(Object data, Node next) { this.data = data; this.next = next; } public Object getData() { return data; } // ...}
public class Node<T extends Comparable<T>> { private T data; private Node<T> next; public Node(T data, Node<T> next) { this.data = data; this.next = next; } public T getData() { return data; } // ...}
public class Node { private Comparable data; private Node next; public Node(Comparable data, Node next) { this.data = data; this.next = next; } public Comparable getData() { return data; } // ...}
public 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; }}public class MyNode extends Node<Integer> { public MyNode(Integer data) { super(data); } public void setData(Integer data) { System.out.println("MyNode.setData"); super.setData(data); }}
MyNode mn = new MyNode(5);Node n = mn; n.setData("Hello"); Integer x = mn.data;
public volatile void setData(Object obj) { setData((Integer)obj); }