什么是便携性?java如何比其他语言更具可移植性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3925947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 07:01:35  来源:igfitidea点击:

What is portability? How is java more portable than other languages?

javacprogramming-languagesportability

提问by Hari Menon

I wonder how Java is more portable than C, C++ and .NET and any other language. I have read many times about java being portable due to the interpreter and JVM, but the JVM just hides the architectural differences in the hardware, right? We'd still need different JVMs for different machine architectures. What am I missing here? So if someone writes an abstraction layer for C for the most common architectures, let's say the CVM, then any C program will run on those architectures once CVM is installed, isn't it?

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

What exactly is this portability? Can .NET be called portable?

这种便携性究竟是什么?.NET 可以称为可移植吗?

采纳答案by Laurence Gonsalves

Portability isn't a black and white, yes or no kind of thing. Portability is how easily one can I take a program and run it on all of the platforms one cares about.

便携性不是非黑即白,是或不是这样的事情。可移植性是指我可以轻松地将程序运行在人们关心的所有平台上。

There are a few things that affect this. One is the language itself. The Java language spec generally leaves much less up to "the implementation". For example, "i = i++" is undefined in C and C++, but has a defined meaning in Java. More practically speaking, types like "int" have a specific size in Java (eg: int is always 32-bits), while in C and C++ the size varies depending on platform and compiler. These differences alone don't prevent you from writing portable code in C and C++, but you need to be a lot more diligent.

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

Another is the libraries. Java has a bunch of standard libraries that C and C++ don't have. For example, threading, networking and GUI libraries. Libraries of these sorts exist for C and C++, but they aren't part of the standard and the corresponding libraries available can vary widely from platform to platform.

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

Finally, there's the whole question of whether you can just take an executable and drop it on the other platform and have it work there. This generally works with Java, assuming there's a JVM for the target platform. (and there are JVMs for many/most platforms people care about) This is generally not true with C and C++. You're typically going to at leastneed a recompile, and that's assuming you've already taken care of the previous two points.

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

Yes, if a "CVM " existed for multiple platforms, that would make C and C++ more portable -- sort of. You'd still need to write your C code either in a portable way (eg: assuming nothing about the size of an int other than what the standard says) or you'd write to the CVM (assuming it has made a uniform decision for all of these sorts of things across all target platforms). You'd also need to forgo the use of non-standard libraries (no networking, threading or GUI) or write to the CVM-specific libraries for those purposes. So then we're not really talking about making C and C++ more portable, but a special CVM-C/C++ that's portable.

是的,如果一个“CVM”存在于多个平台上,那将使 C 和 C++ 更具可移植性——有点。您仍然需要以可移植的方式编写您的 C 代码(例如:除了标准所说的之外,不假设任何关于 int 大小的内容)或者您将写入 CVM(假设它已经为所有目标平台上的所有这些类型的东西)。您还需要放弃使用非标准库(无网络、线程或 GUI)或出于这些目的写入 CVM 特定库。那么我们并不是真正在谈论使 C 和 C++ 更具可移植性,而是一种特殊的可移植的 CVM-C/C++。

Once again, portability isn't a black and white thing. Even with Java there can still be incompatibilities. The GUI libraries (especially AWT) were kind of notorious for having inconsistent behavior, and anything involving threads can behave differently if you get sloppy. In general, however, it's a lot easier to take a non-trivial Java program written on one platform and run it on another than it is to do the same with a program written in C or C++.

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

回答by Chris Thompson

Java is portable from the perspective of the developer: code written in Java can be executed in any environment without the need to recompile. C is not portable because not only is it tied to a specific OS in many cases, it is also always tied to a specific hardware architecture once it has been compiled. The same is true for C++. .Net is more portable than C/C++, as it also relies on a virtual machine and is therefore not tied to a specific hardware architecture at compile-time, but it is limited to Windows machines (officially).

从开发人员的角度来看,Java 是可移植的:用 Java 编写的代码可以在任何环境中执行,而无需重新编译。C 是不可移植的,因为它不仅在许多情况下与特定的操作系统相关联,而且在编译后始终与特定的硬件架构相关联。对于 C++ 也是如此。.Net 比 C/C++ 更具可移植性,因为它也依赖于虚拟机,因此在编译时不依赖于特定的硬件架构,但它仅限于 Windows 机器(官方)。

You are correct, the JVM is platform-specific (it has to be!), but when you say Java is portable, you are talking about it from a developer standpoint and standard Java developers do not write the JVM, they use it :-).

你是对的,JVM 是特定于平台的(它必须是!),但是当你说 Java 是可移植的时,你是从开发人员的角度谈论它,标准 Java 开发人员不编写 JVM,他们使用它:- )。

Edit@Raze2Dust To address your question. Yes, you could. In fact, you could make Java platform-specific by writing a compiler that would generate machine code rather than bytecode. But as some of the other comments suggest, why would you do that? You'd have to create an interpreter that maps the compiled code to operations in the same way the JVM works. So the long and short of it is, absolutely, you definitely could, but why would you?

编辑@Raze2Dust 来解决您的问题。是的,你可以。事实上,您可以通过编写一个生成机器码而不是字节码的编译器来使 Java 平台特定。但正如其他一些评论所暗示的那样,你为什么要这样做?您必须创建一个解释器,以与 JVM 的工作方式相同的方式将编译后的代码映射到操作。因此,无论是长还是短,您绝对可以,但为什么要这样做?

回答by Brian Agnew

You need the JVM for different architectures, but of course your Java programs run on that JVM. So once you have a JVM for an architecture, then your Java programs are available for that architecture.

您需要用于不同架构的 JVM,但当然您的 Java 程序运行在该 JVM 上。因此,一旦您拥有用于架构的 JVM,那么您的 Java 程序就可用于该架构。

So I can write a Java program, compile it down to Java bytecode (which is architecture-agnostic), and that means I can run it on any JVM on any architecture. The JVM abstracts away the underlying architecture and my program runs on a virtual machine.

所以我可以编写一个 Java 程序,将它编译成 Java 字节码(与架构无关),这意味着我可以在任何架构的任何 JVM 上运行它。JVM 抽象了底层架构,我的程序在虚拟机上运行。

回答by Bozho

When you write a Java program, it runs on all platforms that have JVM written for them - Windows, Linux, MacOS, etc.

当您编写 Java 程序时,它会在为它们编写 JVM 的所有平台上运行——Windows、Linux、MacOS 等。

If you write a C++ program, you'll have to compile it specifically for each platform.

如果您编写 C++ 程序,则必须针对每个平台专门编译它。

Now, it is said that the motto of Java "write once, run everywhere" is a myth. It's not quite true for desktop apps, which need interaction with many native resources, but each JavaEE application can be run on any platform. Currently I'm working on windows, and other colleagues are working on Linux - without any problem whatsoever.

现在,据说 Java 的座右铭“一次编写,到处运行”已成为一个神话。对于需要与许多本机资源交互的桌面应用程序而言,情况并非如此,但每个 JavaEE 应用程序都可以在任何平台上运行。目前我在 Windows 上工作,其他同事在 Linux 上工作 - 没有任何问题。

(Another thing related to portability is JavaEE (enterprise edition). It is said that applications written with JavaEE technologies run in any JavaEE-certified application server. This, however, is not true at least until JavaEE6. (see here))

(与可移植性相关的另一件事是 JavaEE(企业版)。据说用 JavaEE 技术编写的应用程序可以在任何 JavaEE 认证的应用程序服务器中运行。然而,至少在 JavaEE6 之前,情况并非如此。(请参阅此处))

回答by Kirk Woll

The idea is that the Java languageis portable (or more accurately, the compiled byte-code is portable). You are correct that each VM requires a specific implementation for a given hardware profile. However, once that effort has been made, alljava bytecode will run on that platform. You write the java/bytecode once, and it runs on any JVM.

这个想法是 Java语言是可移植的(或者更准确地说,编译的字节码是可移植的)。对于给定的硬件配置文件,每个 VM 都需要特定的实现,这是正确的。但是,一旦做出这种努力,所有的Java 字节码都将在该平台上运行。您编写一次 java/字节码,它可以在任何 JVM 上运行。

.NET is quite similar, but with a far lower emphasis on the principle. The CLR is analogous to the JVM and it has its own bytecode. Mono exists on *nix, but you are correct that it is not "official".

.NET 非常相似,但对原理的重视程度要低得多。CLR 类似于 JVM,它有自己的字节码。Mono 存在于 *nix 上,但您是对的,它不是“官方的”。

回答by Peter Tillemans

Portability is a measure for the amount of effort to make a program run on another environment than where it originated.

可移植性是衡量使程序在不同于其起源地的另一个环境中运行所付出的努力。

Now you can debate if a JVM on Linux is a different environment than on Windows (I would argue yes), but the fact remains that in many cases there is zero effort involved if you take care of avoiding a few gotchas.

现在您可以争论 Linux 上的 JVM 是否与 Windows 上的环境不同(我认为是的),但事实仍然是,在许多情况下,如果您注意避免一些问题,则涉及的工作量为零。

The CVM you are talking about is very much what the POSIX libraries and the runtime libraries try to provide, however there are big implementation differences which make the hurdles high to cross. Certainly in the case of Microsoft and Apple these are probably intentionally so in order to keep developers from bringing out products on competing platforms.

您正在谈论的 CVM 是 POSIX 库和运行时库试图提供的,但是存在很大的实现差异,这使得障碍难以跨越。当然,在微软和苹果的情况下,这些可能是故意的,以防止开发人员在竞争平台上推出产品。

On the .net front, if you can stick to what mono provides, an open source .Net implementation, you will enjoy roughly the same kind of portability as Java, but since mono is significantly behind the Windows versions, this is not a popular choice. I do not know how popular this is for server based development where I can imagine it is less of an issue.

在 .net 方面,如果你能坚持使用 mono 提供的开源 .Net 实现,你将享受与 Java 大致相同的可移植性,但由于 mono 明显落后于 Windows 版本,这不是一个流行的选择. 我不知道这对于基于服务器的开发有多流行,我可以想象它不是一个问题。

回答by Buhake Sindi

Portability or as written in Wikipedia, Software Portabilityis the ability to reuse the same software (code) across multiple environments (OSes). The java JVM is a JVM that can be run on any operating systems it was designed for: Windows, Linux, Mac OSes, etc.

可移植性或如维基百科中所写,软件可移植性是在多个环境 (OS) 中重用相同软件(代码)的能力。java JVM 是一种 JVM,可以在其设计的任何操作系统上运行:Windows、Linux、Mac OS 等。

On .NET, it is possible to port your software to different platforms. From Wikipedia:

在 .NET 上,可以将您的软件移植到不同的平台。来自维基百科

The design of the .NET Framework allows it to theoretically be platform agnostic, and thus cross-platform compatible. That is, a program written to use the framework should run without change on any type of system for which the framework is implemented.

.NET Framework 的设计使其在理论上与平台无关,因此跨平台兼容。也就是说,为使用该框架而编写的程序应该在实现该框架的任何类型的系统上无需更改即可运行。

And because Microsoft never implemented the .NET framework outside of Windows and seeing that .NET is platform agnostic, Monohas made it possible to run .NET applications and compile code to run in Linux.

由于微软从未在 Windows 之外实现过 .NET 框架,并且看到 .NET 与平台无关,Mono使得运行 .NET 应用程序和编译代码以在 Linux 中运行成为可能。

For languages such as C++, Pascal, etc. you will have to go to each OS and build it on that platform in order to run it on that platform. The EXE file in Windows isn't the same as the .soin linux (the machine code) since both uses different libraries to talk to the kernel and each OS has its own kernel.

对于 C++、Pascal 等语言,您必须转到每个操作系统并在该平台上构建它才能在该平台上运行它。Windows 中的 EXE 文件与.solinux 中的(机器代码)不同,因为两者都使用不同的库来与内核通信,并且每个操作系统都有自己的内核。

回答by Codemwnci

WORE - Write Once Run Everywhere

WORE - 一次编写到处运行

In reality, this is limited to the platforms that have a JVM, but this covers off the majority of platforms you would wish to deploy to. It is almost a half-way between an interpreted language, and a compiled language, gaining the benefits of both.

实际上,这仅限于具有 JVM 的平台,但这涵盖了您希望部署到的大多数平台。它几乎介于解释型语言和编译型语言之间,获得了两者的好处。

回答by Ken

You ask if one could write a "C VM". Not exactly. "Java" is a big term used by Sun to mean a lot of things, including both the programming language, and the virtual machine. "C" is just a programming language: it's up to the compiler and OS and CPU to decide what format the resulting binary should be.

您问是否可以编写“C VM”。不完全是。“Java”是 Sun 使用的一个重要术语,用于表示很多东西,包括编程语言和虚拟机。“C”只是一种编程语言:由编译器、操作系统和 CPU 决定生成的二进制文件应该是什么格式。

C is sometimes said to be portable becauseit doesn't specify the runtime. The people who wrote your compiler were able to pick things that make sense for that platform. The downside is that C is low-level enough, and platforms are different enough, that it's common for C programs to work fine on one system and not at all on another.

C 有时被称为可移植的,因为它没有指定运行时。编写你的编译器的人能够选择对那个平台有意义的东西。缺点是 C 足够低级,平台也足够不同,C 程序在一个系统上正常工作而在另一个系统上完全不工作是很常见的。

If you combine the C language with a specific ABI, you could define a VM for it, analogous to the JVM. There are a few things like this already, for example:

如果您将 C 语言与特定的 ABI 结合起来,您可以为它定义一个 VM,类似于 JVM。已经有一些这样的事情,例如:

  • The "Intel Binary Compatibility Specification" is an example of such an ABI (which almost nobody uses today)
  • "Microsoft Windows" could also be such an ABI (though a huge and underspecified one), for which Wine is one VM that runs programs written for it
  • "MS-DOS", for which dosemu is one VM
  • "Linux" is one of the more popular ones today, whose programs can be run by Linux itself, NetBSD, or FreeBSD
  • "PA-RISC", for which HP's Dynamowas a JIT-like VM
  • “英特尔二进制兼容性规范”就是这种 ABI 的一个例子(今天几乎没有人使用)
  • “Microsoft Windows”也可能是这样的 ABI(虽然是一个巨大且未指定的 ABI),Wine 是一个运行为它编写的程序的 VM
  • “MS-DOS”,其中 dosmu 是一个 VM
  • “Linux”是当今比较流行的一种,它的程序可以由 Linux 本身、NetBSDFreeBSD 运行
  • “PA-RISC”,HP 的 Dynamo是类似 JIT 的 VM

All of these C VMs are in fact a real machine -- nobody, AFAIK, has ever made a C VM that was purely virtual. This isn't surprising, since C was designed to run efficiently on hardware, so you might as well make it run normally on one system. As HP showed, you can still make a JIT to run the code more efficiently, even on the same platform.

所有这些 C 虚拟机实际上都是一台真正的机器——没有人,AFAIK,曾经制作过一个纯虚拟的 C 虚拟机。这并不奇怪,因为 C 被设计为在硬件上高效运行,所以您不妨让它在一个系统上正常运行。正如 HP 所展示的那样,您仍然可以通过 JIT 来更有效地运行代码,即使在同一平台上也是如此。

回答by Charles Salvia

As others have already said, portability is somewhat of a fuzzy concept. From a certain perspective, C is actually moreportable than Java. C makes very few assumptions about the underlying hardware. It doesn't even assume that there are 8 bits in a byte, or that negative numbers should be represented using two's complement. Theoretically, as long as you have a Von Neumann based machine and a compiler, you're good to go with C.

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

In fact, a "Hello world" program written in C is going to work on many more platforms than a "Hello world" program written in Java. You could probably get the same "hello world" program to work on a PDP-11and an iPhone.

事实上,与用 Java 编写的“Hello world”程序相比,用 C 编写的“Hello world”程序将在更多平台上运行。您可能会在PDP-11和 iPhone上使用相同的“hello world”程序。

However, the reality is that most real-worldprograms do a lot more than output "Hello world". Java has a reputation for being more portable than C because in practice, it takes a lot more effort to port real-world C programs to different platforms than real-world Java programs.

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

This is because the C language is really ANSI-C, which is an extremely general-purpose, bare-bones language. It has no support for network programming, threading, or GUI development. Therefore, as soon as you write a program which includes any of those things, you have to fall back on a less-portable extensionto C, like Win32 or POSIX or whatever.

这是因为 C 语言实际上是 ANSI-C,它是一种非常通用的准系统语言。它不支持网络编程、线程或 GUI 开发。因此,一旦您编写了包含任何这些内容的程序,您就必须依赖于 C的可移植性较差的扩展,例如 Win32 或 POSIX 或其他任何东西。

But with Java, network programming, threading, and GUI tools are defined by the language and built into each VM implementation.

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

That said, I think a lot of programmers also underestimatethe progress modern C/C++ has made in regard to portability these days. POSIX goes a long way towards providing cross-platform threading, and when it comes to C++, Boost provides networking and threading libraries which are basically just as portable as anything in Java. These libraries have some platform-specific quirks, but so does Java.

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

Essentially, Java relies on each platform having a VM implementation which will interpret byte code in a predictable way, and C/C++ relies on libraries which incorporate platform specific code using the preprocessor (#ifdefs). Both strategies allow for cross platform threading, networking, and GUI development. It's simply that Java has made faster progress than C/C++ when it comes to portability. The Java language spec had threading, networking and GUI development almost from day one, whereas the Boost networking library only came out around 2005, and it wasn't until 2011 with C++11 that standard portable threading was included in C++.

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