我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
当前回答
关于差异是什么,已经有很多很好的答案,所以让我给出一个稍微不同的角度,并补充为什么。
正如已经解释过的,主要的区别是类型擦除,即Java编译器擦除泛型类型,它们不会出现在生成的字节码中。然而,问题是:为什么会有人这么做呢?这说不通啊!真的是这样吗?
那么,还有什么选择呢?如果你不在语言中实现泛型,你在哪里实现它们呢?答案是:在虚拟机中。这打破了向后兼容性。
另一方面,类型擦除允许混合泛型客户端和非泛型库。换句话说:在Java 5上编译的代码仍然可以部署到Java 1.4。
然而,微软决定打破泛型的向后兼容性。这就是为什么。net泛型比Java泛型“更好”。
当然,孙不是白痴也不是懦夫。他们“退缩”的原因是,当他们引入泛型时,Java明显比。net更古老,更广泛。(它们在两个世界几乎同时被引入。)打破向后兼容性将是一个巨大的痛苦。
换句话说:在Java中,泛型是语言的一部分(这意味着它们只适用于Java,而不是其他语言),在。net中,它们是虚拟机的一部分(这意味着它们适用于所有语言,而不仅仅是c#和Visual Basic.NET)。
Compare this with .NET features like LINQ, lambda expressions, local variable type inference, anonymous types and expression trees: these are all language features. That's why there are subtle differences between VB.NET and C#: if those features were part of the VM, they would be the same in all languages. But the CLR hasn't changed: it's still the same in .NET 3.5 SP1 as it was in .NET 2.0. You can compile a C# program that uses LINQ with the .NET 3.5 compiler and still run it on .NET 2.0, provided that you don't use any .NET 3.5 libraries. That would not work with generics and .NET 1.1, but it would work with Java and Java 1.4.
其他回答
注:我没有足够的观点来评论,所以请随意将此作为评论移动到适当的答案。
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必须打破向后兼容性来支持真正的泛型。
维基百科上有很多比较Java/ c#泛型和Java泛型/ c++模板的文章。关于泛型的主要文章似乎有点混乱,但它确实有一些很好的信息。
Anders Hejlsberg自己在这里描述了“c#、Java和c++中的泛型”的区别。
在Java中,泛型只是编译器级别的,所以你得到:
a = new ArrayList<String>()
a.getClass() => ArrayList
注意,'a'的类型是数组列表,而不是字符串列表。所以香蕉列表的类型等于()猴子列表。
可以这么说。
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。