我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
当前回答
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。
其他回答
在Java中,泛型只是编译器级别的,所以你得到:
a = new ArrayList<String>()
a.getClass() => ArrayList
注意,'a'的类型是数组列表,而不是字符串列表。所以香蕉列表的类型等于()猴子列表。
可以这么说。
c++模板实际上比c#和Java模板强大得多,因为它们在编译时进行计算,并支持专门化。这允许模板元编程,并使c++编译器等价于图灵机(即在编译过程中,你可以计算任何可以用图灵机计算的东西)。
跟进我之前的帖子。
模板是c++在智能感知上如此糟糕的主要原因之一,不管使用的是哪种IDE。由于模板专门化,IDE永远无法真正确定给定成员是否存在。考虑:
template <typename T>
struct X {
void foo() { }
};
template <>
struct X<int> { };
typedef int my_int_type;
X<my_int_type> a;
a.|
现在,光标位于指定的位置,IDE很难判断成员a是否具有或具有什么。对于其他语言,解析将是简单的,但对于c++,需要在此之前进行相当多的计算。
情况变得更糟。如果my_int_type也定义在类模板中呢?现在它的类型依赖于另一个类型参数。在这里,即使是编译器也会失败。
template <typename T>
struct Y {
typedef T my_type;
};
X<Y<int>::my_type> b;
经过一些思考,程序员会得出结论,这段代码与上面的相同:Y<int>::my_type解析为int,因此b应该是与a相同的类型,对吗?
错了。当编译器试图解析这条语句时,它实际上还不知道Y<int>::my_type !因此,它不知道这是一个类型。它可以是其他东西,例如成员函数或字段。这可能会导致歧义(尽管在本例中没有),因此编译器会失败。我们必须显式地告诉它我们引用了一个类型名:
X<typename Y<int>::my_type> b;
现在,代码编译完成。要了解这种情况下如何产生歧义,请考虑以下代码:
Y<int>::my_type(123);
这段代码语句完全有效,并告诉c++执行对Y<int>::my_type的函数调用。但是,如果my_type不是函数而是类型,则此语句仍然有效,并执行特殊的强制转换(函数样式强制转换),通常是构造函数调用。编译器无法判断我们的意思,所以我们必须在这里消除歧义。
注:我没有足够的观点来评论,所以请随意将此作为评论移动到适当的答案。
Contrary to popular believe, which I never understand where it came from, .net implemented true generics without breaking backward compatibility, and they spent explicit effort for that. You don't have to change your non-generic .net 1.0 code into generics just to be used in .net 2.0. Both the generic and non-generic lists are still available in .Net framework 2.0 even until 4.0, exactly for nothing else but backward compatibility reason. Therefore old codes that still used non-generic ArrayList will still work, and use the same ArrayList class as before. Backward code compatibility is always maintained since 1.0 till now... So even in .net 4.0, you still have to option to use any non-generics class from 1.0 BCL if you choose to do so.
所以我不认为java必须打破向后兼容性来支持真正的泛型。
Anders Hejlsberg自己在这里描述了“c#、Java和c++中的泛型”的区别。