为什么认为Java比其他语言(如C ++)更具移植性?


16

Java开发人员“为每个平台编写特定的JRE”和C ++语言为“为每个平台编写C ++编译器”之间有什么区别?

Answers:


33

Java可以在任何地方运行一次进行编译。C ++是一次编写的,可以在任何地方编译。


3
好吧,您显然没有太多的GUI开发经验。(正在等待Qt ...)

27
任何声称C ++“在任何地方都可以编写一次编译的人”从来没有移植过C ++程序...
BlueRaja-Danny Pflughoeft 2011年

7
我同意BlueRaja。移植C ++程序比移植编译器意味着更多。C ++广泛存在于关键环境中,在这些环境中,诸如int的大小或文件系统的实现之类的事情可能会带来如此大的变化。移植不仅仅意味着重新编译。
rahmu 2011年

8
@ Pubby8不,可移植性问题也来自相当标准的代码,这些代码做出了不可移植的假设,例如关于字节序的假设(请注意,在Java中您也可能会遭受痛苦),对齐方式和基本类型的大小。
R. Martinho Fernandes

5
编写一次,到处调试。
bhagyas 2011年

25

并非每次都要做“为每个平台编写特定的JRE”。只需将JRE移植到新平台即可。该任务通常由程序和/或平台的核心维护者/开发者来完成。在决定谁以及如何移植JRE时,可能会考虑很多因素。除其他事项外,它取决于其下发布的许可(我听说Java是开源的,所以我猜有人可以做到)。有趣的轶事,史蒂夫·乔布斯Steve Jobs)在一年前就不想在Mac上移植Java做了很多事情

关键不在于如何或由谁移植JRE,而是事实是,一旦移植了JRE,理论上每个Java应用程序现在都应该可以轻松地在新机器上运行。从这个意义上讲,JRE形成了一个抽象层,完全隐藏了机器,从而便于移植。

但是,现实并非总是如此。我不会说可移植性是一个“神话”,但是确实它并不那么完美。例如,Java有一个名为的包JNI,该包允许绕过JRE发送本机调用,从而阻止了完美的无缝可移植性,Java爱好者喜欢将其称为“在任何地方运行一次写入”。

如评论中所述,C ++的可移植性方法不同。一方面,它是一种编译语言,并且这些二进制文件几乎总是特定于平台的。因此,c ++可执行文件将永远不可移植(不同于Java)。另一方面,移植编译器有时就足够了。社区发现,通过移植编译器以及该语言的某些核心库,源代码(而不是二进制文件)可以移植。

但是,C ++在诸如编译器,内核,实时系统,嵌入式系统等关键系统中得到了广泛的使用。当谈到可移植性时,C ++的一个“低级”方面不容忽视。


4
可移植性不是神话。完美的可移植性是。
马尔科姆

“他的地方在于Java与C ++截然不同,后者的每个应用程序都是“特定于机器的”,并且不能在不修改代码的情况下移植。事实并非如此,这取决于依赖项。如果仅使用标准库和带有可移植到目标的源的库,则只需编写一次代码并在每个目标上编译。如果您编写的代码可以移植而无需修改C ++中的代码,那么您唯一需要修改的就是构建脚本。并非在所有情况下都如此。
Klaim 2011年

我们不要忘记C ++既可以用作高级语言,也可以用作低级语言。32位int与64位int有很大不同的程序中使用了许多C ++代码。当然,高级将始终是可移植的。但这远非C ++概括
rahmu 2011年

我认为您可能误解了我的意思:您可以使用int或任何标准类型编写正确的C ++,而无需打扰底层的东西。看看boost库,大多数只是高级代码,对于许多C ++开源项目都是如此。您可以“降低”级别,如果需要,还可以避免使用任何特定的代码,直到需要使用平台特定的API。但是,如果不需要,则可以编写可在任何地方使用的C ++。可以避免对平台的依赖,并且通常在库代码中。
Klaim 2011年

只是为了确保我很清楚:我并不是说所有C ++代码都是可移植的,而是说您的陈述是错误的。您可能想要用以下方式修复它:“这是Java与C ++截然不同的地方,其中每个应用程序都是“特定于机器的”,并且不能在不修改代码的情况下移植,或者,如果代码确实是可移植的且构建的,则不能移植。脚本可以管理新目标,而无需至少进行一次编译。”
克拉姆

14

不只是语言,还包括库。

Java和C ++都提供跨平台的库。Java提供了更丰富的设置。


2
Java默认提供更丰富的设置。可以为C ++找到相同的库,它们只是标准库的一部分,您只需要决定要使用哪些库即可(尤其是如果未安装它们,这并非易事)。
马丁·约克

将Java的标准库与C ++的库进行比较并不是真正有效的比较。无论您是比较每个标准库,还是比较每个库的整体,Java都提供了更丰富的集合。
安迪·托马斯

3
绝对不同意这一点。Java库中的任何可用库都已可供某些库中的C ++使用。我喜欢Java将所有功能都放在一个地方的事实,但是说Java更丰富只是不正确。也许您要寻找的形容词是“更整合的”
Martin York

1
+1会再次投票。我认为库是可移植性的最大因素。如果您使用C / C ++进行除纯计算之外的任何工作,那么某些库(尤其是系统库的某些部分)在Windows和Unix之间将存在根本性的差异,而在不同类型的Unix之间将存在显着差异。这使得移植变得困难。Java基本上没有这个问题。
汤姆·安德森

1
@Andy Thomas-Cramer:我没有比较任何东西(您似乎是)。我是说你的说法不正确。Java拥有的优势之一(我们都为此而深爱)是所有标准库都集中在一处。说他们更富有只是不准确。
马丁·约克

7

不同之处在于Java 无需重新编译即可在任何平台上运行。每个平台都有一个C ++编译器根本不一样。


6

所有以“区别在于...”或任何非常相似的词开头的答案基本上都是错误的(对不起,但这就是生活)。两者之间确实存在两个不同的区别。

一个(经常提到)是一个已编译的Java程序可以(或至少应该)在任何符合Java的实现上运行,因此,即使在编译之后,您仍然可以将Java程序从一个平台移至另一个平台,而无需重新编译。 。C ++(至少正常情况下)要求针对每个目标平台进行重新编译。

另一个是Java(至少是尝试)确保所有正确编写的Java将是可移植的。至少从理论上讲,您不应编写任何不可移植的代码。

C ++允许您执行很多不可移植的事情。C ++标准包含有关许多不可移植内容的“警告”(例如,告诉您将获得实现定义的行为或未定义的行为),但它并不一定试图阻止您执行这些操作。仅举例来说,如果您要为使用PCI总线的硬件编写操作系统,则可能需要读取/写入PCI配置内存。这显然不能移植到没有PCI总线的系统,但是如果您要为带有PCI总线的硬件编写操作系统,则非常有必要。即使它显然不能移植,C ++也允许它。


C ++对PCI总线或硬件一无所知。
日航

当然不是,那些是平台特定的东西,必须包含在平台特定的库中。正如Java可以根据需要具有特定于平台的库一样。
jwenting 2011年

1
@Nikko:它知道它没有什么,但它可以让你用什么了解它。
杰里·科芬

@jwenting:不同之处在于您可以用C ++编写平台特定的库,但通常不能用Java编写它们。
杰里·科芬

6

您误解了前提。Java 程序具有很高的可移植性,因为JVM提供了保证相同的标准行为。C ++程序具有与实际硬件更接近的标准化环境,因此该程序需要能够处理各种平台特定的细节,例如int的大小,字对齐等。

JVM本身不是非常可移植的。将高性能JVM移植到另一个平台或CPU架构是一项艰巨的任务。


最后一句话+1!
rahmu 2011年

2

区别在于Java(不是缩写)程序可以以可以在安装了JVM的任何计算机上运行的形式分发,但是C ++通常作为源代码分发,这对用户非常不友好,也可以作为一堆分发不同平台的不同二进制文件。


??有针对JVM的C ++编译器和有针对本机代码的Java编译器。您能否引用C ++语言规范的特定部分,其中指出C ++程序必须作为源代码或特定于平台的二进制文件分发?
约尔格W¯¯米塔格

在那里,我编辑我的回答要少用明确的语言
科林

2

Java被认为具有可移植性的原因之一是,它对于必须如何计算算术表达式具有特定的规则,并且禁止实现以任何其他方式对它们进行求值,即使以强制方式对它们进行求值时,也需要比以更准确的方式求值更慢的代码。时尚。

例如,给定

long thing1(int x) {
  return (x+1)-1L;
}
double thing2(int x, float y) {
  return x/y;
}

的价值thing1(2147483647)thing2(1123456700,11234567.0f)需要是-2147483649L和99.9999923706054688,分别,即使算术正确的价值观会2147483647L和100.0,即使在某些平台上的代码生成的数字,不正确的结果会慢于代码生成正确的结果(在某些64位平台上,在(x + 1)之后强制执行包装行为将需要额外的指令,而在8x87平台上,float与简单加载相比,将1123456700的值四舍五入为a 将需要额外的指令直接将其保存到扩展精度寄存器中)。


1
对于一个老问题,实际上,新的答案实际上增加了一些价值:Java具有非常精确的算术要求,并且与C ++相比,原始数据类型当然具有特定的大小和语义。到目前为止,没有其他答案提及此问题。

@Snowman:您如何看待所选的特定示例?就我个人而言,如果我正在设计一种语言,则在不使用(int)第一个示例的第一个示例的(x+1)子表达式float的第二个x参数的子表达式的情况下,都不会使Java的值返回到Java的值,但是显然我没有设计该语言。
2014年

我认为它们很有道理。对于任何语言而言,重要的是要具有定义明确的语义。无论是否同意给定的语言设计决策,最重要的是能够查看代码并知道其工作方式。Java通常会这样做,很少有未定义行为的情况。

1

辅助工具的工作量确实相似,不同之处在于其他地方。为某个平台编译了C ++程序后,如果要在其他平台上使用它,则必须再次对其进行编译。但是,编译完Java程序后,可以将其移动到具有运行时环境的任何其他平台,而无需重新编译。


1

回答“可移植性是神话吗?”的标题,而不是“在可移植性,Java或C ++方面哪个更好”,我会说部分可移植性是可能的,但是完全可移植性却是一个神话。

我坚持要写的东西(适用于此问题)是,开发人员不再仅使用编程语言,而是使用完整的编程框架。

这些框架包括库,数据库,图形界面。

哪种编程语言,或者哪种编程框架更易于移植?

好吧,这取决于您的应用程序。正在努力实现。


1

事情是“你”不要写JRE,而是写在任何 JRE 上运行的Java代码。“您”确实编写了可能需要进行更改的C ++代码,然后才能在其他平台上进行编译。


0

许多人在说“它是100%可移植的”或类似的短语时忘记或不考虑Java的现实。

最近,几乎所有主要的公司/软件公司都至少有1种Java的自制实现以及相关的JRE,有些仍在维护它,例如,Microsoft,IBM和Apple都有自己的Java版本,反映了它们的关于行业和语言的发展方向的自己的想法和思想。

“便携式”怎么样?无论您身在何处,都可以使用JRE。

而且这没有考虑Sun / Oracle在做什么。

关于Java代码和图形服务器为何Java代码在可移植性方面与C和C ++的差距并不大的示例,Apple为自己的JRE提供了GUI框架的非标准实现,因此,对于想要使用Java为Apple机器创建/移植GUI的任何人来说,都是头疼和双重工作,他们基本上被迫与Quartz打交道(就“杠杆”和高级语言而言,这是怎么回事?)。

有时,即使最常用的单词也不能真正反映人们通常赋予它们的含义,对我而言,Java世界中的“可移植性”一词在常识上更像是“外表”。如果您采用Java而不是其他语言(至少在Java诞生之时),那么从商业和财务角度看,您的前景会更好,因为您已经在一方面完成了大量工作(在任何方面都获得了JRE) ,并且您的代码库很可能是可移植的,您需要更少的资源来移植程序,就是这样,无论所说的资源是金钱,时间还是人力都无关紧要,与其他技术相比,这就是Java的极限,它正在降低该极限。

当然,如果您接受Java的前提,这是正确的,这意味着带有垃圾回收的虚拟机,这意味着与本机语言相比,如果您真的想从CPU或服务器场中挤出最大的资源,它将消耗更多的资源。除非您真的资源不足或公司规模很小,否则不要以为可以采用Java。

我仍然必须找到一个简单的Java应用程序,该应用程序的每行代码或功能(也就是没有任何平台特定的东西)仅包含一个版本,并且在所有主要的JRE中都是100%可移植的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.