我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
当前回答
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。
其他回答
Java和c#在它们的第一个语言版本之后都引入了泛型。然而,在引入泛型时,核心库的变化方式有所不同。c#的泛型不仅仅是编译器的魔法,因此不可能在不破坏向后兼容性的情况下泛化现有的库类。
例如,在Java中,现有的集合框架是完全泛化的。Java没有集合类的泛型版本和遗留的非泛型版本。在某种程度上,这要干净得多——如果你需要在c#中使用一个集合,那么使用非泛型版本的理由真的很少,但是那些遗留类仍然存在,使环境变得混乱。
另一个显著的区别是Java和c#中的Enum类。Java的Enum有这样一个看起来有点曲折的定义:
// java.lang.Enum Definition in Java
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
(见Angelika Langer对为什么会这样的解释非常清楚。从本质上讲,这意味着Java可以提供从字符串到Enum值的类型安全访问:
// Parsing String to Enum in Java
Colour colour = Colour.valueOf("RED");
比较一下c#版本:
// Parsing String to Enum in C#
Colour colour = (Colour)Enum.Parse(typeof(Colour), "RED");
因为Enum在引入泛型之前就已经存在于c#中,所以如果不改变定义就会破坏现有的代码。因此,像集合一样,它以这种遗留状态保留在核心库中。
c++模板实际上比c#和Java模板强大得多,因为它们在编译时进行计算,并支持专门化。这允许模板元编程,并使c++编译器等价于图灵机(即在编译过程中,你可以计算任何可以用图灵机计算的东西)。
11个月后,但我认为这个问题已经准备好了一些Java通配符的东西。
这是Java的一个语法特性。假设你有一个方法:
public <T> void Foo(Collection<T> thing)
假设您不需要在方法体中引用类型T。您声明了一个名称T,然后只使用了一次,那么为什么还要为它想一个名称呢?相反,你可以这样写:
public void Foo(Collection<?> thing)
问号要求编译器假装您声明了一个普通的命名类型参数,该参数只需要在该位置出现一次。
用通配符可以做的事情,用命名类型参数也可以做(在c++和c#中,这些事情总是这样做的)。
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。
维基百科上有很多比较Java/ c#泛型和Java泛型/ c++模板的文章。关于泛型的主要文章似乎有点混乱,但它确实有一些很好的信息。