我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
当前回答
注:我没有足够的观点来评论,所以请随意将此作为评论移动到适当的答案。
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必须打破向后兼容性来支持真正的泛型。
其他回答
11个月后,但我认为这个问题已经准备好了一些Java通配符的东西。
这是Java的一个语法特性。假设你有一个方法:
public <T> void Foo(Collection<T> thing)
假设您不需要在方法体中引用类型T。您声明了一个名称T,然后只使用了一次,那么为什么还要为它想一个名称呢?相反,你可以这样写:
public void Foo(Collection<?> thing)
问号要求编译器假装您声明了一个普通的命名类型参数,该参数只需要在该位置出现一次。
用通配符可以做的事情,用命名类型参数也可以做(在c++和c#中,这些事情总是这样做的)。
看起来,在其他非常有趣的建议中,有一个是关于改进泛型和打破向后兼容性的:
Currently, generics are implemented using erasure, which means that the generic type information is not available at runtime, which makes some kind of code hard to write. Generics were implemented this way to support backwards compatibility with older non-generic code. Reified generics would make the generic type information available at runtime, which would break legacy non-generic code. However, Neal Gafter has proposed making types reifiable only if specified, so as to not break backward compatibility.
Alex Miller关于Java 7提案的文章
维基百科上有很多比较Java/ c#泛型和Java泛型/ c++模板的文章。关于泛型的主要文章似乎有点混乱,但它确实有一些很好的信息。
Anders Hejlsberg自己在这里描述了“c#、Java和c++中的泛型”的区别。
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。