26


17

移植性とは何ですか? javaは他の言語よりもどのように移植性がありますか?

JavaはC、C ++ 、. NETおよびその他の言語よりも移植性が高いのではないかと思います。 私はインタプリタとJVMのためにJavaが移植可能であることを何度も読みましたが、JVMはハードウェアのアーキテクチャの違いを隠しているだけですよね? マシンのアーキテクチャごとに異なるJVMが必要です。 私はここで何が足りないのですか? だから誰かが最も一般的なアーキテクチャ、たとえばCVMのCの抽象化レイヤーを書いた場合、CVMがインストールされると、Cプログラムはそれらのアーキテクチャで実行されますよね?

この移植性は正確に何ですか? .NETはポータブルと呼ばれますか?

11 Answer


39


移植性は白黒ではなく、はいもいや何もありません。 移植性は、プログラムを取得して、関心のあるすべてのプラットフォームで実行できることです。

これに影響するものがいくつかあります。 1つは言語そのものです。 Java言語の仕様では、一般に「実装」までの距離がずっと短くなります。 たとえば、「i = i 」はCおよびC では未定義ですが、Javaでは定義された意味を持ちます。 より実際的に言えば、「int」などの型はJavaで特定のサイズを持ちます(たとえば、intは常に32ビットです)が、CおよびC ではサイズはプラットフォームとコンパイラによって異なります。 これらの違いだけでは、CおよびC で移植可能なコードを書くことを妨げることはありませんが、もっと熱心に取り組む必要があります。

もう1つはライブラリです。 Javaには、CおよびC にはない多数の標準ライブラリがあります。 たとえば、スレッド、ネットワーク、およびGUIライブラリ。 これらの種類のライブラリはCおよびC に存在しますが、それらは標準の一部ではなく、対応する利用可能なライブラリはプラットフォームごとに大きく異なる可能性があります。

最後に、実行可能ファイルを他のプラットフォームにドロップして、そこで実行できるかどうかという疑問があります。 これは通常、ターゲットプラットフォーム用のJVMがあると仮定して、Javaで機能します。 (そして、多くの/ほとんどの人々が気にするプラットフォーム用のJVMがあります)これは一般にCとC ++では当てはまりません。 通常、_least_で再コンパイルが必要になりますが、これは前の2つのポイントを既に処理していることを前提としています。

はい、複数のプラットフォームに「CVM」が存在する場合、CおよびC の移植性が向上します。 移植可能な方法でCコードを記述する必要があります(たとえば、標準の言う以外にintのサイズについて何も仮定しない)またはCVMに書き込む必要がありますすべてのターゲットプラットフォームでこれらの種類のすべてが行われます)。 また、非標準ライブラリ(ネットワーク、スレッド、またはGUIなし)の使用をやめるか、それらの目的のためにCVM固有のライブラリに書き込む必要があります。 ですから、CとC の移植性を高めることではなく、移植性のある特別なCVM-C / C ++について話しています。

繰り返しになりますが、移植性は白黒のものではありません。 Javaを使用しても、非互換性が残る可能性があります。 GUIライブラリ(特にAWT)は一貫性のない振る舞いをすることで悪名高く、スレッドに関係するものはだらしない場合は異なる振る舞いをする可能性があります。 ただし、一般に、あるプラットフォームで作成された重要なJavaプログラムを別のプラットフォームで実行して実行する方が、CまたはC ++で作成されたプログラムで実行するよりもはるかに簡単です。


20


他の人がすでに言ったように、移植性はやや曖昧な概念です。 特定の観点から、Cは実際にはJavaよりも* more *移植性があります。 Cは、基礎となるハードウェアについてほとんど仮定しません。 1バイトに8ビットがあることや、2の補数を使用して負の数を表すことも想定していません。 理論的には、フォンノイマンベースのマシンとコンパイラがあれば、Cを使用しても問題ありません。

実際、Cで書かれた「Hello world」プログラムは、Javaで書かれた「Hello world」プログラムよりも多くのプラットフォームで動作します。 同じ「hello world」プログラムを入手して、http://en.wikipedia.org/wiki/Pdp-11 [PDP-11]とiPhoneで動作させることができます。

しかし、現実には、ほとんどの「現実世界」のプログラムは「Hello world」を出力するだけではありません。 Javaは、実際にCプログラムを実際のJavaプログラムとは異なるプラットフォームに移植するのに多大な労力を要するため、Cよりも移植性が高いという評判があります。

これは、C言語が実際にANSI-Cであるためです。ANSI-Cは非常に汎用的な最低限の言語です。 ネットワークプログラミング、スレッド化、またはGUI開発はサポートされていません。 したがって、これらのいずれかを含むプログラムを作成するとすぐに、Win32やPOSIXなど、移植性の低い_extension_に頼らなければなりません。

しかし、Javaでは、ネットワークプログラミング、スレッド、およびGUIツールは言語によって定義され、各VM実装に組み込まれます。

そうは言っても、多くのプログラマーは、最近のC / C の移植性に関する進歩を「過小評価」していると思います。 POSIXはクロスプラットフォームスレッドの提供に大きく貢献しており、C に関しては、Boostは基本的にJavaのあらゆるものと同様に移植性のあるネットワークおよびスレッドライブラリを提供します。 これらのライブラリには、プラットフォーム固有のいくつかの癖がありますが、Javaも同様です。

基本的に、Javaは、バイトコードを予測可能な方法で解釈するVM実装を持つ各プラットフォームに依存し、C / C は、プリプロセッサ( `#ifdef`s)を使用してプラットフォーム固有のコードを組み込むライブラリに依存します。 両方の戦略により、クロスプラットフォームのスレッド化、ネットワーキング、およびGUI開発が可能になります。 移植性に関しては、JavaがC / C よりも速く進歩したというだけです。 Java言語仕様には、ほぼ1日目からスレッド化、ネットワーキング、およびGUI開発がありましたが、Boostネットワーキングライブラリは2005年ごろに登場し、C 11ではC に標準のポータブルスレッドが含まれていました。


7


Javaプログラムを作成すると、Windows、Linux、MacOSなど、JVMが記述されたすべてのプラットフォームで実行されます。

C ++プログラムを作成する場合、プラットフォームごとに特別にコンパイルする必要があります。

現在、Javaのモットーである「1回書き込み、どこでも実行」は神話であると言われています。 多くのネイティブリソースとの対話を必要とするデスクトップアプリにはあまり当てはまりませんが、各JavaEEアプリケーションはどのプラットフォームでも実行できます。 現在、私はWindowsに取り組んでおり、他の同僚もLinuxに取り組んでいます-何の問題もありません。

(移植性に関連するもう1つのことは、JavaEE(エンタープライズ版)です。 JavaEEテクノロジで記述されたアプリケーションは、JavaEE認定のアプリケーションサーバーで実行されると言われています。 ただし、これは少なくともJavaEE6までは当てはまりません。 (http://techblog.bozho.net/?p=213 [こちらを参照]))


5


移植性は、プログラムを元の環境とは別の環境で実行するための労力の尺度です。

LinuxのJVMがWindowsのJVMとは異なる環境であるかどうかについて議論することができます(私はそうだと主張します)が、事実は、多くの場合、いくつかの落とし穴を避けることに注意すれば、労力がかからないという事実が残っています。

あなたが話しているCVMは、POSIXライブラリとランタイムライブラリが提供しようとしているものです。しかし、ハードルを越えるには実装上の大きな違いがあります。 確かにMicrosoftとAppleの場合、これらはおそらく開発者が競合するプラットフォームで製品を持ち出さないようにするために意図的にそうなっているでしょう。


3


Javaは開発者の観点から移植性があります。Javaで記述されたコードは、再コンパイルすることなく、あらゆる環境で実行できます。 Cは多くの場合特定のOSに結び付けられるだけでなく、コンパイルされた後は常に特定のハードウェアアーキテクチャにも結び付けられるため、移植性がありません。 同じことがC にも当てはまります。 .NetはC / C よりも移植性が高く、仮想マシンにも依存するため、コンパイル時に特定のハードウェアアーキテクチャに縛られませんが、Windowsマシン(公式)に限定されます。

確かに、JVMはプラットフォーム固有です(そうする必要があります!)が、Javaが移植可能であると言うとき、開発者の観点からそれについて話しているので、標準のJava開発者はJVMを記述せず、それを使用します:- )。

編集 @ Raze2Dust質問に対処します。 はい、できます。 実際、バイトコードではなくマシンコードを生成するコンパイラーを作成することにより、Javaプラットフォーム固有にすることができます。 しかし、他のコメントのいくつかが示唆しているように、なぜそうするのですか? JVMの動作と同じ方法で、コンパイルされたコードを操作にマップするインタープリターを作成する必要があります。 だから、それの長短は、絶対に、あなたは間違いなく可能ですが、なぜあなたはでしょうか?


2


「C VM」を書くことができるかどうか尋ねます。 ではない正確に。 「Java」は、プログラミング言語と仮想マシンの両方を含む多くのことを意味するためにサンが使用する大きな用語です。 「C」は単なるプログラミング言語です。結果のバイナリの形式を決定するのは、コンパイラとOSおよびCPU次第です。

Cは移植性があると言われることがあります。 あなたのコンパイラを書いた人々は、そのプラットフォームにとって意味のあるものを選ぶことができました。 欠点は、Cが十分​​に低レベルであり、プラットフォームが十分に異なるため、Cプログラムが1つのシステムで正常に機能し、別のシステムではまったく機能しないことです。

C言語を特定のABIと組み合わせると、JVMに似た、そのためのVMを定義できます。 たとえば、次のようなものがすでにいくつかあります。

  • 「Intel Binary Compatibility Specification」はそのような例です ABI(今日はほとんど誰も使用しません)

  • 「Microsoft Windows」もそのようなABIになる可能性があります(ただし、 指定不足)、Wineはそのために書かれたプログラムを実行する1つのVM

  • dosemuが1つのVMである「MS-DOS」

  • 「Linux」は今日最も人気のあるものの1つで、そのプログラムは Linux自体、http://www.netbsd.org/docs/guide/en/chap-linux.html [NetBSD]、またはhttp://www.freebsd.org/doc/handbook/linuxemu.html[FreeBSD ]

  • 「PA-RISC」、そのため HP’s DynamoはJITのようなVMでした

これらのC VMはすべて実際には実際のマシンです。AFAIKは誰も、純粋に仮想的なC VMを作成したことはありません。 Cはハードウェア上で効率的に実行するように設計されているため、これは驚くことではありません。したがって、1つのシステムで通常どおり実行することもできます。 HPが示したように、同じプラットフォーム上でも、コードをより効率的に実行するJITを作成できます。


2


Javaは* three *の移植性の異なるタイプを提供します。

*ソースコードの移植性:*特定のJavaプログラムは、基盤となるCPU、オペレーティングシステム、またはJavaコンパイラに関係なく、同じ結果を生成する必要があります。

  • CPUアーキテクチャの移植性:*現在のJavaコンパイラは、まだ存在しないCPUのオブジェクトコード(バイトコードと呼ばれる)を生成します。 Javaプログラムを実行する実際のCPU、Javaインタープリター、または仮想マシンごとに、Jコードを「実行」します。 この存在しないCPUにより、Javaインタープリターが存在する任意のCPUで同じオブジェクトコードを実行できます。

  • OS / GUIの移植性:* Javaは、架空のOSや架空のGUIと通信するライブラリ関数のセット(awt、util、langなどのJava提供ライブラリに含まれる)を提供することでこの問題を解決します。 JVMが仮想CPUを提供するように、Javaライブラリは仮想OS / GUIを提供します。 すべてのJava実装は、この仮想OS / GUIを実装するライブラリを提供します。 これらのライブラリを使用して、必要なOSおよびGUI機能のポートをかなり簡単に提供するJavaプログラム。


1


さまざまなアーキテクチャーにJVMが必要ですが、JavaプログラムはもちろんそのJVMで実行されます。 したがって、アーキテクチャ用のJVMがあれば、そのアーキテクチャ用のJavaプログラムを使用できます。

したがって、Javaプログラムを作成し、Javaバイトコード(アーキテクチャに依存しない)にコンパイルすることができます。つまり、どのアーキテクチャのどのJVMでも実行できます。 JVMは基盤となるアーキテクチャを抽象化し、私のプログラムは仮想マシンで実行されます。


1


その考え方は、Java 言語_が移植可能であるということです(より正確には、コンパイルされたバイトコードは移植可能です)。 各VMには、特定のハードウェアプロファイルの特定の実装が必要であることは正しいです。 ただし、その努力がなされると、_all javaバイトコードがそのプラットフォームで実行されます。 java / bytecodeを1回記述すると、任意のJVMで実行されます。

NET is quite similar, but with a far lower emphasis on the principle.

CLRはJVMに似ており、独自のバイトコードを持っています。 Monoは* nixに存在しますが、「公式」ではないのは正しいことです。


1


移植性、またはウィキペディアに記載されているhttp://en.wikipedia.org/wiki/Software_portability[Software Portability]は、複数の環境(OS)で同じソフトウェア(コード)を再利用する機能です。 java JVMは、Windows、Linux、Mac OSなどのために設計されたすべてのオペレーティングシステムで実行できるJVMです。

NETでは、ソフトウェアをさまざまなプラットフォームに移植できます。 Wikipediaから:

_ .NET Frameworkの設計により、理論的にはプラットフォームに依存しないため、クロスプラットフォーム互換になります。 つまり、フレームワークを使用するように作成されたプログラムは、フレームワークが実装されているどのタイプのシステムでも変更なしで実行する必要があります。 _

また、MicrosoftはWindows以外に.NETフレームワークを実装せず、.NETがプラットフォームに依存しないことを認識していないため、http://en.wikipedia.org/wiki/Mono_%28software%29 [Mono]により.NETアプリケーションを実行できるようになりました。 Linuxで実行するコードをコンパイルします。

C ++、Pascalなどの言語の場合 そのプラットフォームで実行するには、各OSに移動して、そのプラットフォームでビルドする必要があります。 WindowsのEXEファイルは、Linux(マシンコード)の `.so`とは異なります。両方ともカーネルと通信するために異なるライブラリを使用し、各OSには独自のカーネルがあります。