Answers:
Java可以在任何地方运行一次进行编译。C ++是一次编写的,可以在任何地方编译。
并非每次都要做“为每个平台编写特定的JRE”。只需将JRE移植到新平台即可。该任务通常由程序和/或平台的核心维护者/开发者来完成。在决定谁以及如何移植JRE时,可能会考虑很多因素。除其他事项外,它取决于其下发布的许可(我听说Java是开源的,所以我猜有人可以做到)。有趣的轶事,史蒂夫·乔布斯(Steve Jobs)在一年前就不想在Mac上移植Java做了很多事情。
关键不在于如何或由谁移植JRE,而是事实是,一旦移植了JRE,理论上每个Java应用程序现在都应该可以轻松地在新机器上运行。从这个意义上讲,JRE形成了一个抽象层,完全隐藏了机器,从而便于移植。
但是,现实并非总是如此。我不会说可移植性是一个“神话”,但是确实它并不那么完美。例如,Java有一个名为的包JNI
,该包允许绕过JRE发送本机调用,从而阻止了完美的无缝可移植性,Java爱好者喜欢将其称为“在任何地方运行一次写入”。
如评论中所述,C ++的可移植性方法不同。一方面,它是一种编译语言,并且这些二进制文件几乎总是特定于平台的。因此,c ++可执行文件将永远不可移植(不同于Java)。另一方面,移植编译器有时就足够了。社区发现,通过移植编译器以及该语言的某些核心库,源代码(而不是二进制文件)可以移植。
但是,C ++在诸如编译器,内核,实时系统,嵌入式系统等关键系统中得到了广泛的使用。当谈到可移植性时,C ++的一个“低级”方面不容忽视。
不只是语言,还包括库。
Java和C ++都提供跨平台的库。Java提供了更丰富的设置。
所有以“区别在于...”或任何非常相似的词开头的答案基本上都是错误的(对不起,但这就是生活)。两者之间确实存在两个不同的区别。
一个(经常提到)是一个已编译的Java程序可以(或至少应该)在任何符合Java的实现上运行,因此,即使在编译之后,您仍然可以将Java程序从一个平台移至另一个平台,而无需重新编译。 。C ++(至少正常情况下)要求针对每个目标平台进行重新编译。
另一个是Java(至少是尝试)确保所有正确编写的Java将是可移植的。至少从理论上讲,您不应编写任何不可移植的代码。
C ++允许您执行很多不可移植的事情。C ++标准包含有关许多不可移植内容的“警告”(例如,告诉您将获得实现定义的行为或未定义的行为),但它并不一定试图阻止您执行这些操作。仅举例来说,如果您要为使用PCI总线的硬件编写操作系统,则可能需要读取/写入PCI配置内存。这显然不能移植到没有PCI总线的系统,但是如果您要为带有PCI总线的硬件编写操作系统,则非常有必要。即使它显然不能移植,C ++也允许它。
您误解了前提。Java 程序具有很高的可移植性,因为JVM提供了保证相同的标准行为。C ++程序具有与实际硬件更接近的标准化环境,因此该程序需要能够处理各种平台特定的细节,例如int的大小,字对齐等。
JVM本身不是非常可移植的。将高性能JVM移植到另一个平台或CPU架构是一项艰巨的任务。
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 将需要额外的指令直接将其保存到扩展精度寄存器中)。
(int)
第一个示例的第一个示例的(x+1)
子表达式float
的第二个x
参数的子表达式的情况下,都不会使Java的值返回到Java的值,但是显然我没有设计该语言。
辅助工具的工作量确实相似,不同之处在于其他地方。为某个平台编译了C ++程序后,如果要在其他平台上使用它,则必须再次对其进行编译。但是,编译完Java程序后,可以将其移动到具有运行时环境的任何其他平台,而无需重新编译。
许多人在说“它是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%可移植的。