泛类型

Java的泛类型,完全是语言层次的泛类型,在class文件层次和jvm层次是不存在泛类型的说法的。

所有的泛类型都在编译的时候被jdk自动转型。所以这种,只是在写程序的时候,能够给开发人员减少一定的CastClass的错误。

对于C#的泛类型,与之有截然的不同,具体请参考MS$的说法:

运行库中的泛型

将泛型类型或方法编译为 Microsoft 中间语言 (MSIL) 时,它包含将其标识为具有类型参数的元数据。泛型类型的 MSIL 的使用因所提供的类型参数是值类型还是引用类型而不同。

第一次用值类型作为参数来构造泛型类型时,运行库会创建专用泛型类型,将提供的参数代入到 MSIL 中的适当位置。对于每个用作参数的唯一值类型,都会创建一次专用泛型类型。

例如,假设您的程序代码声明了一个由整数构造的堆栈,如下所示:

Stack<int> stack;

在 此位置,运行库生成 Stack <T> 类的专用版本,并相应地用整数替换其参数。现在,只要程序代码使用整数堆栈,运行库就会重用生成的专用 Stack<T> 类。在下面的示例中,创建了整数堆栈的两个实例,它们共享 Stack<int> 代码的单个实例:

Stack<int> stackOne = new Stack<int>();
Stack<int> stackTwo = new Stack<int>();

但 是,如果在程序代码中的其他位置创建了另一个 Stack<T> 类,这次使用不同的值类型(如 long 或用户定义的结构)作为其参数,则运行库会生成泛型类型的另一版本(这次将在 MSIL 中的适当位置代入 long)。由于每个专用泛型类本身就包含值类型,因此不再需要转换。

对于引用类型,泛型的工作方式略有不同。第一次使用任何引用类型构造 泛型类型时,运行库会创建专用泛型类型,用对象引用替换 MSIL 中的参数。然后,每次使用引用类型作为参数来实例化构造类型时,无论引用类型的具体类型是什么,运行库都会重用以前创建的泛型类型的专用版本。之所以可以 这样,是因为所有引用的大小相同。

例如,假设您有两个引用类型:一个 Customer 类和一个 Order 类,并且进一步假设您创建了一个 Customer 类型的堆栈:

class Customer { }
class Order { }

Stack<Customer> customers;

在此情况下,运行库生成 Stack<T> 类的一个专用版本,该版本不是存储数据,而是存储稍后将填写的对象引用。假设下一行代码创建另一个引用类型的堆栈,称为 Order:

Stack<Order> orders = new Stack<Order>();

不同于值类型,对于 Order 类型不创建 Stack<T> 类的另一个专用版本。而是创建 Stack<T> 类的一个专用版本实例,并将 orders 变量设置为引用它。假设接下来您遇到一行创建 Customer 类型堆栈的代码:

customers = new Stack<Customer>();

与 前面使用 Order 类型创建的 Stack<T> 类一样,创建了专用 Stack<T> 类的另一个实例,并且其中所包含的指针被设置为引用 Customer 类型大小的内存区域。因为引用类型的数量会随程序的不同而大幅变化,C# 泛型实现将编译器为引用类型的泛型类创建的专用类的数量减小到一个,从而大幅减小代码量的增加。

此外,使用类型参数实例化泛型 C# 类时,无论它是值类型还是引用类型,可以在运行时使用反射查询它,并且可以确定它的实际类型和类型参数。

对于C++的模板,就更强大了。


C++ 模板和 C# 泛型之间的区别

C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性。此外,C# 并不尝试提供 C++ 模板所提供的所有功能。在实现层面,主要区别在于,C# 泛型类型替换是在运行时执行的,从而为实例化的对象保留了泛型类型信息。

以下是 C# 泛型和 C++ 模板之间的主要差异:

C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。

C# 不允许非类型模板参数,如 template C<int i> {}。

C# 不支持显式专用化,即特定类型的模板的自定义实现。

C# 不支持部分专用化:类型参数子集的自定义实现。

C# 不允许将类型参数用作泛型类型的基类。

C# 不允许类型参数具有默认类型。

在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。

C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。

其实在使用上,给人的感觉 他们都有共同的点,但是底层实现上有很大差别的,尤其是C++的模板。  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值