14.4 Explain the difference between templates in C++ and generics in Java.
在Java中,泛式编程Generic Programming的实现是通过一种就做类型擦除Type Erasure的机制来实现的。当源码转为Java虚拟机JVM的字节代码时擦除参数的类型,例如下面的例子:
Vector<String> vector = new Vector<String>(); vector.add(new String("hello")); String str = vector.get(0);
在编译过程中,被重写为:
Vector vector = new Vector(); vector.add(new String("hello")); String str = (String) vector.get(0);
这跟C++中有很大的不同。在C++中,模板是一个宏设置Macro Set,编译器对每一个类型的模板代码都创建一份拷贝。验证这一点可以通过以下事实: MyClass<Foo>的一个实例不会跟MyClass<Bar>共享一个静态变量,但是两个MyClass<Foo>之间会共享一个静态变量,参见如下代码:
template<class T> class MyClass { public: static int val; MyClass(int v) { val = v; } }; template<typename T> int MyClass<T>::val; class Foo; class Bar; int main() { MyClass<Foo> *foo1 = new MyClass<Foo>(10); MyClass<Foo> *foo2 = new MyClass<Foo>(15); MyClass<Bar> *bar1 = new MyClass<Bar>(20); MyClass<Bar> *bar2 = new MyClass<Bar>(35); cout << foo1->val << endl; // will equal 15 cout << foo2->val << endl; // will equal 15 cout << bar1->val << endl; // will equal 35 cout << bar2->val << endl; // will equal 35 return 0; }
而在Java中,静态变量会在所有的MyClass的实例中共享,不论其参数是否相同,参见下列代码:
public class Foo {} public class Bar {} public static class MyClass<T> { public static int val; public MyClass(int v) { val = v; } } public static void main (String[] args) { System.out.println("Hello World!"); MyClass<Foo> foo1 = new MyClass<Foo>(10); MyClass<Foo> foo2 = new MyClass<Foo>(15); MyClass<Bar> bar1 = new MyClass<Bar>(20); MyClass<Bar> bar2 = new MyClass<Bar>(35); System.out.println(foo1.val); // will equal 35 System.out.println(foo2.val); // will equal 35 System.out.println(bar1.val); // will equal 35 System.out.println(bar2.val); // will equal 35 }
本文转自博客园Grandyang的博客,原文链接:Java模板[CareerCup] 14.4 Templates,如需转载请自行联系原博主。