我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
我主要使用Java,泛型相对较新。我一直读到Java做出了错误的决定,或者。net有更好的实现等等。
那么,c++, c#, Java在泛型上的主要区别是什么?利弊各有哪些?
当前回答
最大的抱怨是字体擦除。在这种情况下,不在运行时强制执行泛型。这里有一些关于这个主题的Sun文档的链接。
泛型是按类型实现的 Erasure:泛型类型信息为 之后,仅在编译时出现 它被编译器擦除。
其他回答
Anders Hejlsberg自己在这里描述了“c#、Java和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#在它们的第一个语言版本之后都引入了泛型。然而,在引入泛型时,核心库的变化方式有所不同。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#中,所以如果不改变定义就会破坏现有的代码。因此,像集合一样,它以这种遗留状态保留在核心库中。
11个月后,但我认为这个问题已经准备好了一些Java通配符的东西。
这是Java的一个语法特性。假设你有一个方法:
public <T> void Foo(Collection<T> thing)
假设您不需要在方法体中引用类型T。您声明了一个名称T,然后只使用了一次,那么为什么还要为它想一个名称呢?相反,你可以这样写:
public void Foo(Collection<?> thing)
问号要求编译器假装您声明了一个普通的命名类型参数,该参数只需要在该位置出现一次。
用通配符可以做的事情,用命名类型参数也可以做(在c++和c#中,这些事情总是这样做的)。
c++模板实际上比c#和Java模板强大得多,因为它们在编译时进行计算,并支持专门化。这允许模板元编程,并使c++编译器等价于图灵机(即在编译过程中,你可以计算任何可以用图灵机计算的东西)。