java 泛型与c_C#和Java …中的泛型和C中的模板有什么区别?

我会添加我的声音的噪音,并采取刺刀使事情清楚:

C#泛型允许你声明这样的东西。

List foo = new List();

然后编译器将阻止你把不是Person的东西放到列表中。

在后台,C#编译器只是将List进入.NET dll文件,但在运行时JIT编译器会构建一组新的代码,就好像你编写了一个专门用于包含人的列表类 – 像ListOfPerson。

这样做的好处是它使它真的很快。没有投射或任何其他的东西,并且因为dll包含的信息,这是一个人的列表,其他代码,看看它后来使用反射可以告诉它包含Person对象(所以你得到intellisense等)。

这样做的缺点是旧的C#1.0和1.1代码(在他们添加泛型之前)不理解这些新的List< something&gt ;,所以你必须手动将事情转换回旧的List与它们互操作。这不是一个大问题,因为C#2.0二进制代码不向后兼容。只有这样,如果你升级一些旧的C#1.0 / 1.1代码到C#2.0

Java泛型允许你声明这样的东西。

ArrayList foo = new ArrayList();

在表面上看起来是一样的,它的排序是。编译器还会阻止你把不是Person的东西放到列表中。

区别是幕后发生了什么。与C#不同,Java不会去构建一个特殊的ListOfPerson – 它只是使用一直在Java中的普通的ArrayList。当你从数组中取出东西时,通常的Person p =(Person)foo.get(1);铸造舞蹈还有待完成。编译器会为你保存按键,但速度命中/投射仍然会发生,就像它总是。

当人们提到“类型擦除”,这是他们在说什么。编译器为你插入转换,然后“擦除”它的意思是一个Person列表的事实,而不仅仅是Object

这种方法的好处是,不理解泛型的旧代码不必关心。它仍然处理相同的旧ArrayList,因为它总是有。这在Java世界中更为重要,因为他们希望支持使用带有泛型的Java 5编译代码,并让它在旧的1.4或以前的JVM上运行,微软故意决定不去处理。

缺点是我之前提到的速度命中,也因为没有ListOfPerson伪类或类似的任何东西进入.class文件,代码,以后看它(用反射,或者如果你把它从另一个集合,它被转换为对象等)不能以任何方式告诉它的意思是一个只包含Person而不只是任何其他数组列表的列表。

C模板允许你声明这样的东西

std::list* foo = new std::list();

它看起来像C#和Java泛型,它会做你认为应该做的,但在幕后不同的事情发生。

它与C#泛型最常见的是它构建特殊的伪类,而不是像java那样丢弃类型信息,但是它是一个完全不同的鱼。

C#和Java都生成为虚拟机设计的输出。如果你写了一些具有Person类的代码,在这两种情况下,一个Person类的一些信息将会进入.dll或.class文件,JVM / CLR会做这件事。

C产生原始x86二进制代码。一切都不是一个对象,没有底层的虚拟机,需要知道一个Person类。没有拳击或开箱,并且功能不必属于类,或任何东西。

因此,C编译器没有限制你可以用模板做什么 – 基本上任何可以手动编写的代码,你可以得到模板来为你写。

最明显的例子是添加东西:

在C#和Java中,泛型系统需要知道类的可用方法,并且需要将其传递给虚拟机。告诉它的唯一方法是通过硬编码实际的类,或使用接口。例如:

string addNames( T first, T second ) { return first.Name() + second.Name(); }

该代码不会在C#或Java中编译,因为它不知道类型T实际上提供了一个名为Name()的方法。你必须告诉它 – 在C#中像这样:

interface IHasName{ string Name(); };

string addNames( T first, T second ) where T : IHasName { .... }

然后你必须确保你传递给addNames的东西实现IHasName接口等等。 java语法是不同的(),但它遇到相同的问题。

这个问题的“经典”情况是试图写一个这样做的函数

string addNames( T first, T second ) { return first + second; }

你实际上不能写这段代码,因为没有办法用它的方法声明一个接口。你失败了。

C没有这些问题。编译器不关心传递类型到任何虚拟机 – 如果你的对象有一个.Name()函数,它会编译。如果他们不,它不会。简单。

所以你有它 :-)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值