什么是便携性?Java如何比其他语言更具可移植性?[已关闭]

2022-09-01 10:10:12

我想知道Java如何比C,C++,.NET以及任何其他语言更具可移植性。我已经读过很多关于java由于解释器和JVM而可移植的,但是JVM只是隐藏了硬件中的架构差异,对吧?对于不同的机器架构,我们仍然需要不同的JVM。我在这里错过了什么?因此,如果有人为最常见的架构(比如CVM)编写了一个C抽象层,那么一旦安装了CVM,任何C程序都将在这些架构上运行,不是吗?

这种便携性到底是什么?.NET 可以称为便携式吗?


答案 1

便携性不是非黑即白的,是或不是那种东西。可移植性是一个人可以多么容易地将一个程序放在一个人关心的所有平台上运行它。

有几件事会影响这一点。一个是语言本身。Java语言规范通常留给“实现”的要少得多。例如,“i = i++”在C和C++中未定义,但在Java中具有定义的含义。更实际地说,像“int”这样的类型在Java中具有特定的大小(例如:int始终是32位),而在C和C++中,大小因平台和编译器而异。仅凭这些差异并不能阻止你用C和C++编写可移植代码,但你需要更加勤奋。

另一个是图书馆。Java有一堆C和C++没有的标准库。例如,线程、网络和 GUI 库。这些类型的库适用于C和C++,但它们不是标准的一部分,并且相应的可用库可能因平台而异。

最后,还有一个问题,即您是否可以将可执行文件拖放到另一个平台上,然后让它在那里工作。这通常适用于Java,假设目标平台有一个JVM。(人们关心的许多/大多数平台都有JVM)对于 C 和 C++,通常不是这样。您通常至少需要重新编译,这是假设您已经处理了前两点。

是的,如果一个“CVM”存在于多个平台上,这将使C和C++更具可移植性。你仍然需要以可移植的方式编写你的C代码(例如:除了标准所说的之外,没有假设int的大小),或者你可以写信给CVM(假设它已经对所有目标平台上的所有这些事情做出了统一的决定)。您还需要放弃使用非标准库(没有网络,线程或GUI)或为此目的写入特定于CVM的库。因此,我们并不是在谈论使C和C++更便携,而是一种特殊的CVM-C / C++,它是可移植的。

再一次,便携性不是一个非黑即白的事情。即使使用Java,仍然可能存在不兼容性。GUI库(尤其是AWT)因行为不一致而臭名昭著,如果你变得草率,任何涉及线程的东西都会有不同的行为。然而,一般来说,在一个平台上编写一个不平凡的Java程序并在另一个平台上运行它比用C或C++编写的程序做同样的事情要容易得多。


答案 2

正如其他人已经说过的那样,可移植性在某种程度上是一个模糊的概念。从某种角度来看,C实际上比Java更具可移植性。C对底层硬件的假设很少。它甚至不假设一个字节中有8位,或者负数应该用二的补码来表示。从理论上讲,只要你有一个基于冯·诺依曼的机器和一个编译器,你就可以使用C。

事实上,用C语言编写的“Hello world”程序将比用Java编写的“Hello world”程序在更多的平台上工作。你可能会得到同样的“hello world”程序来运行PDP-11和iPhone。

然而,现实情况是,大多数现实世界的程序所做的不仅仅是输出“Hello world”。Java以比C语言更具可移植性而闻名,因为在实践中,将现实世界C程序移植到不同的平台比将现实世界的Java程序移植到不同的平台需要更多的努力。

这是因为C语言实际上是ANSI-C,它是一种非常通用的,基本的语言。它不支持网络编程、线程或 GUI 开发。因此,一旦你编写了一个包含这些东西的程序,你就必须回退到一个不太便携的C扩展,比如Win32或POSIX等等。

但是,使用 Java,网络编程、线程和 GUI 工具由语言定义,并内置于每个 VM 实现中。

也就是说,我认为很多程序员也低估了现代C/C++在可移植性方面取得的进展。POSIX在提供跨平台线程方面走了很长的路,当涉及到C++时,Boost提供了网络和线程库,这些库基本上与Java中的任何东西一样可移植。这些库有一些特定于平台的怪癖,但Java也是如此。

从本质上讲,Java依赖于每个平台都有一个VM实现,该实现将以可预测的方式解释字节码,而C / C++依赖于使用预处理器合并平台特定代码的库。这两种策略都允许跨平台线程、网络和 GUI 开发。简单地说,Java在可移植性方面取得了比C /C++更快的进展。Java语言规范几乎从第一天起就有线程,网络和GUI开发,而Boost网络库仅在2005年左右问世,直到2011年的C++11,标准的可移植线程才包含在C++中。#ifdef