由于本人之前是c++程序员,现在转行成了java程序员,所以在学习java的时候,感觉和c++很像,特别是java的设计者也曾说,设计这么灵感主要来自于c++,所以看到相似的地方总是要来总结一番的。
1.java泛型的概念
其实我们在编写类和方法的时候,我们一般使用的是具体的类型(要么是基本的类型,要么是自定义的类,)而用泛型可以使类型参数化,这样就可以编写更通用的代码,可以应用于多种类型的代码。
2.c++模板的概念
编写带有参数化类型的通用版本,让编译器自动生成针对不同类型的具体版本。
java泛型最主要的目的就是用来指定容器要持有什么类型的对象,而且有编译器来保证类型的正确性。
3.c++模版和java泛型的区别
3.1c++模板可以使用基本类型(int、short、long),而java泛型不能使用基本类型做类型参数。(为什么)
3.2.java在使用泛型的时候不会知道具体的类型信息,但是c++是可以知道的。
因为:java泛型是通过擦除实现的,这意味着你在使用泛型的时候,任何具体的类型信息都没擦除掉了。你唯一知道的就是你在使用一个对象。因此List和List在运行时其实是一个类型,两种都会被擦除为其原生的类型List。
示例 c++
//: generics/Templates.cpp
#include
using namespace std;
template class Manipulator {
T obj;
public:
Manipulator(T x) { obj = x; }
void manipulate() { obj.f(); }
};
class HasF {
public:
void f() { cout << "HasF::f()" << endl; }
};
int main() {
HasF hf;
Manipulator manipulator(hf);
manipulator.manipulate();
} /* Output:
HasF::f()
///:~
这个代码是可以正确运行的,在Manipulator类里面存储了T类型的对象,然后在manipulate里面调用的T对象的f()方法,它是怎么知道f()方法是参数类型T的呢?
答:当你实例化这个模版的时候,c++编译器将进行检查。他在实例化Manipulator manipulator(hf)的这一刻,它看到HasF有一个方法f()。所以c++中,当模版实例化的时候,模板代码知道其模版参数的类型。
但是在java中
class Manipulator {
private T obj;
public Manipulator(T x) { obj = x; }
// Error: cannot find symbol: method f():
public void manipulate() { obj.f(); }
}
public class Manipulation {
public static void main(String[] args) {
HasF hf = new HasF();
Manipulator manipulator =
new Manipulator(hf);
manipulator.manipulate();
}
} ///:~
编译会报错,
因为java编译器无法将manipulator里面的能够在obj上调用f()方法的这一需求映射到HasF拥有f()方法这一事实上。所以java是不知道具体的类型信息的。为了解决这个问题,要使用到泛型边界,以此告知编译器只能接受遵循这个边界的类型。
代码如下
class Manipulator2 {
private T obj;
public Manipulator2(T x) { obj = x; }
public void manipulate() { obj.f(); }
} ///:~
边界 声明了T是从HasF导出的类型或具有类型HasF,所以就可以在Obj上面调用f()了。
上面的效果其实就是编译器会把参数类型替换成他的擦除,就像上面的案例。T擦除到了HasF,就好像在类的声明中用HasF替换了T一样。变成如下:
class Manipulator3 {
private HasF obj;
public Manipulator3(HasF x) { obj = x; }
public void manipulate() { obj.f(); }
} ///:~
使用擦除的原因:擦除的核心动机是它使得泛型化的客户端可以调用非泛型化的类库来使用。反之亦然。其实就是“迁移兼容性”。如果没有某种迁移兼容性,所有已经构建很长时间的类库就需要与希望迁移到java泛型上的开发者们说再见了。类库是很重要的,他们对生产效率会产生重要的影响。因此这不是一个可以接受的代价。