首页 / 知识
C ++和Java中的“泛型”类型之间有什么区别?
2023-04-13 17:43:00
What are the differences between “generic” types in C++ and Java?
Java具有泛型,并且C ++使用 它们之间有很大的区别。在C ++中,您不必为泛型类型指定类或接口。这就是为什么您可以创建真正的泛型函数和类,而不必担心松散的键入。
上面的方法添加了两个相同类型的对象,并且可以用于任何具有" +"运算符的类型T。 在Java中,如果要在传递的对象上调用方法,则必须指定一种类型,例如:
在C ++中,泛型函数/类只能在标头中定义,因为编译器会针对不同的类型(使用其调用)生成不同的函数。因此编译速度较慢。在Java中,编译不会带来很大的损失,但是Java使用一种称为"擦除"的技术,其中泛型在运行时被擦除,因此在运行时Java实际上正在调用...
因此,Java中的通用编程并不是真正有用,它只是语法上的一点帮助新的foreach构造。 编辑:以上关于有用性的观点是由一个年轻的自我写成的。 Java的泛型当然有助于类型安全。 Java泛型与C ++模板完全不同。 基本上,在C ++中,模板基本上是经过修饰的预处理器/宏集(注意:由于某些人似乎无法理解类推,因此我并不是说模板处理是宏)。在Java中,它们基本上是语法糖,可以最大程度地减少对象的样板转换。这是对C ++模板与Java泛型的相当不错的介绍。
要详细说明这一点:使用C ++模板时,基本上是在创建代码的另一个副本,就像使用 Java不能那样工作。在Java中,所有对象都来自java.lang.Object,因此,泛型之前,您需要编写如下代码:
因为所有Java集合类型都将Object作为其基本类型,因此您可以在其中放置任何内容。 Java 5推出并添加了泛型,因此您可以执行以下操作:
这就是Java泛型的全部内容:转换对象的包装器。那是因为Java泛型没有改进。他们使用类型擦除。之所以做出此决定,是因为Java泛型出现的太晚了,以至于他们不想破坏向后兼容性(只要需要 在JDK 1.4上可以使用使用Java 5+编译器编译的泛型的类(假定它不使用任何其他需要Java 5+的功能或类)。 这就是为什么Java泛型被称为语法糖。 但是,关于如何执行泛型的决定产生了深远的影响,以至于(一流的)Java Generics FAQ迅速出现,回答了人们对Java Generics的许多问题。 C ++模板具有Java泛型所没有的许多功能:
例如:
确实需要强调的是,具有不同参数的模板调用实际上是不同的类型。他们甚至不共享静态成员。在Java中并非如此。 除了与泛型的区别之外,出于完整性的考虑,这里是C ++和Java(以及另一个)的基本比较。 我也可以建议使用Java思考。作为C ++程序员,对象之类的许多概念已经是天生的,但是存在细微的差异,因此即使您略过部分内容,也应该有介绍性的文本。 学习Java时,您会学到的很多东西都是库(标准库(JDK中附带的库)和非标准库,其中包括Spring等常用的东西)。 Java语法比C ++语法更冗长,并且没有很多C ++功能(例如运算符重载,多重继承,析构函数等),但严格来说也不能使其成为C ++的子集。 C ++具有模板。 Java具有泛型,看上去有点像C ++模板,但是它们非常非常不同。 顾名思义,模板通过为编译器提供一个(等待它……)模板来工作,模板可以通过填充模板参数来生成类型安全的代码。 据我所知,泛型的工作方式相反:编译器使用类型参数来验证使用它们的代码是否是类型安全的,但是生成的代码根本没有类型。 将C ++模板视为一个非常好的宏系统,并将Java泛型视为自动生成类型转换的工具。 C ++模板具有Java泛型所没有的另一个功能是专业化。这使您可以对特定类型使用不同的实现。因此,例如,您可以为int拥有高度优化的版本,而对于其余类型仍然具有通用版本。或者,您可以为指针和非指针类型使用不同的版本。如果要在传递指针时对取消引用的对象进行操作,这将很方便。
Java泛型和集合中对该主题有很好的解释
请在此处阅读完整说明。
基本上,AFAIK,C ++模板为每种类型创建代码副本,而Java泛型使用完全相同的代码。 是的,您可以说C ++模板等效于Java泛型概念(尽管更恰当的说法是Java泛型在概念上等效于C ++)
来自:Java泛型 C ++模板的另一个优点是专业化。
现在,如果使用指针调用sum,则将调用第二个方法;如果使用非指针对象调用sum,则将调用第一个方法;如果使用 Java(和C#)泛型似乎是一种简单的运行时类型替换机制。 C ++模板是一种编译时结构,可让您根据自己的需要修改语言。它们实际上是编译器在编译期间执行的纯功能语言。 我将用一句话概括一下:模板创建新类型,泛型限制现有类型。 下面的答案来自第13章的《破解编码面试解决方案》,我认为这很好。 Java泛型的实现植根于"类型擦除:"的思想,该技术在将源代码转换为Java虚拟机(JVM)字节码时消除了参数化类型。例如,假设您具有以下Java代码:
在编译期间,此代码被重写为:
Java泛型的使用并没有真正改变我们的功能。它使事情变得更漂亮。因此,Java泛型有时被称为"语法糖:"。 这与C ++完全不同。在C ++中,模板本质上是美化的宏集,编译器为每种类型创建模板代码的新副本。事实证明,MyClass实例不会与MyClass共享静态变量。但是,MyClass的两个实例将共享一个静态变量。
在Java中,静态变量在MyClass实例之间共享,而与不同的类型参数无关。 Java泛型和C ++模板还有许多其他差异。这些包括:
@Keith:
该代码实际上是错误的,除了较小的故障(省略了
模板不过是一个宏系统。语法糖。它们在实际编译之前已完全扩展(或者至少,编译器的行为就像实际情况一样)。 例: 假设我们要两个功能。一个函数接受两个数字序列(列表,数组,向量,无论如何),然后返回其内积。另一个函数需要一个长度,生成两个该长度的序列,然后将它们传递给第一个函数,然后返回结果。要注意的是,我们可能在第二个函数中犯了一个错误,因此这两个函数的长度实际上并不相同。在这种情况下,我们需要编译器警告我们。不是在程序运行时,而是在编译时。 在Java中,您可以执行以下操作:
在C#中,您可以编写几乎相同的东西。尝试用C ++重写它,但由于模板无限扩展而无法编译。 |
最新内容
相关内容
查看linux库类型命令?
查看linux库类型命令?,系统,工作,信息,状态,电脑,命令,工具,代码,地址,发行,如何查看Linux上程序或进程用到的库查看程序依赖的动态库:readelflinux终端命令行编程?
linux终端命令行编程?,系统,工作,命令,终端,概念,时间,第一,代码,发行,地方,Linux下5个有趣的命令行技巧介绍我们可以使用history命令来查看曾linux查看接口命令?
linux查看接口命令?,地址,系统,标准,命令,管理,工作,文件,端口,目录,路径,linux命令?1、linux常用命令如下:查看内核版本:uname-a。控制台-》图linux网卡类型命令?
linux网卡类型命令?,网络,系统,地址,信息,设备,状态,服务,名称,名字,网卡,如何配置Linux网卡配置网卡地址:点击 网络(K) 按钮进行配置网络 选择linux编程调用命令?
linux编程调用命令?,系统,标准,管理,工作,基础知识,情况,环境,设备,基础,首页,linux下怎样用c语言调用shell命令可以通过system函数,调用shelllinux编程所需的命令?
linux编程所需的命令?,工作,地址,档案,系统,命令,管理,标准,信息,目录,文件,Linux必须学会的60个命令:文件处理1应用实例如果我们看到一个没有使用linux命令调接口?
使用linux命令调接口?,网络,系统,地址,信息,工具,情况,服务,灵活,电脑,名称,简述grub启动引导程序配置及命令行接口详解grub 命令行接口(一次性linux命令行编程乱码?
linux命令行编程乱码?,环境,统一,乱码,中文,状态,软件,数据,系统,字符集,文件,为什么我进入Linux的终端窗口时,man一条命令出来的都是乱码呢?linux查看命令类型用?
linux查看命令类型用?,信息,系统,情况,命令,实时,工作,设备,电脑,文件,类型,如何区分linux文件类型?1、普通文件类型 Linux中最多的一种文件类linux命令三种类型?
linux命令三种类型?,工作,地址,系统,标准,时间,管理,命令,目录,信息,文件,linux常用命令linux常用命令:查看内核版本:uname-a。图形界面:init5或linux命令添加接口?
linux命令添加接口?,地址,网络,名称,系统,工具,设备,信息,服务,中心,密码,Linux用shell创建子接口称为子shell shell中创建的变量局部于创建它linux编程c命令符?
linux编程c命令符?,工具,代码,系统,保险,环境,文件,程序,命令,终端,编辑,到底怎么在Linux里编写c程序啊?1、学会使用vim/emacs,vim/emacs是linu