JavaがC ++などの他の言語よりも移植性が高いと考えられるのはなぜですか?


16

Java開発者向けの「各プラットフォーム用の特定のJREの作成」とC ++向けの「各プラットフォーム用のC ++コンパイラの作成」の違いは何ですか?

回答:


33

Javaは一度実行するとコンパイルされます。C ++は、一度コンパイルすればどこでもコンパイルできます。


3
さて、GUI開発の経験があまりないことは明らかです。(Qtを待っています...)

27
C ++が「どこでも1回コンパイル」であると主張する人は、C ++プログラムを移植する必要がなかった...
BlueRaja-ダニーPflughoeft

7
BlueRajaに同意します。C ++プログラムの移植は、コンパイラの移植以上のことを意味します。C ++は、intのサイズやファイルシステムの実装などが大きな違いを生む可能性がある重要な環境に最も広く存在します。移植とは、単に再コンパイルすることではありません。
ラーム

8
@ Pubby8いいえ、移植性の問題は、エンディアンネス(Javaで苦しむ可能性もある)、アライメント、および基本型のサイズなど、移植性のない仮定行うかなり標準的なコードからも発生します。
R.マルティーニョフェルナンデス

5
一度書くだけで、どこでもデバッグできます。
バギア

25

「プラットフォームごとに特定のJREを作成する」ことは、毎回行うことではありません。JREを新しいプラットフォームに移植することは、一度だけ行う必要があることです。このタスクは通常、プログラムやプラットフォームのコアメンテナー/開発者によって実行されます。JREを誰とどのように移植するかを決定する際には、多くの要因が関与する可能性があります。とりわけ、公開されているライセンスに依存します(Javaはオープンソースだと聞いているので、誰でもできると思います)。おかしな逸話、Steve JobsはMacでのJavaの移植の面倒を見たくないということについて大いに議論しました 1年ほど前ました。

ポイントは、JREをどのように、または誰が移植するかではなく、一度移植すると、すべてのJavaアプリケーションが理論的には新しいマシンで簡単に実行できるようになるという事実です。その意味で、JREは抽象レイヤーを形成し、マシンを完全に隠して、移植を容易にします。

しかし、現実は常にこのようにきれいではありません。移植性を「神話」と呼ぶほどには行きませんが、完全ではないのは事実です。たとえば、JavaにはJNI、JREをバイパスしてネイティブ呼び出しを送信できるようにするパッケージがあり、Javaファンが「どこでも一度実行して書き込み」と呼んでいる完璧なシームレスな移植性を妨げています。

コメントで述べたように、移植性に対するC ++のアプローチは異なります。一方で、それはコンパイルされた言語であり、それらのバイナリはほとんど常にプラットフォーム固有です。そのため、C ++実行可能ファイルは移植できません(Javaと異なります)。一方、コンパイラの移植で十分な場合もあります。コミュニティは、コンパイラと言語のいくつかのコアライブラリを移植することにより、ソースコード(バイナリではなく)を移植できることを発見しました。

ただし、C ++は、コンパイラ、カーネル、リアルタイムシステム、組み込みシステムなどの重要なシステムで広く使用されています。


4
移植性は神話ではありません。完璧な移植性です。
マルコム

「彼は、JavaがC ++とは非常に異なっており、各アプリケーションは「マシン固有」であり、コードを変更しないと移植できない」それは真実ではありません、依存関係に依存します。標準ライブラリと、ターゲットに移植可能なソースを備えたライブラリのみを使用する場合、一度コーディングして、各ターゲットでコンパイルします。C ++でコードを変更せずに移植できるものをコーディングする場合、変更する必要があるのはビルドスクリプトだけです。それはすべての場合においてさえ真実ではありません。
クライム

C ++を高レベル言語と低レベル言語の両方として使用できることを忘れないでください。32ビット整数が64ビット整数と非常に異なるプログラムでは、多くのC ++コードが使用されます。もちろん、高レベルは常に移植可能です。しかし、C ++の一般化とは
ほど遠い-rahmu

私が言っていることを誤解していると思います。低レベルのものに煩わされることなく、intまたは任意の標準型で正しいC ++を記述できます。ブーストライブラリをご覧ください。ほとんどは高レベルのコードのみであり、多くのC ++オープンソースプロジェクトに当てはまります。あなたは低レベルに「行く」ことができ、もしそうするなら、プラットフォーム固有のAPIを使用する必要があるまで特定のコードを避けることもできます。しかし、必要がなければ、どこでも動作するC ++を書くことができます。プラットフォームへの依存は回避でき、多くの場合ライブラリコードにあります。
クライム

明確にするために、すべてのC ++コードが移植可能であるとは言いません。そのまま、あなたのステートメントは間違っていると言っています。「これは、JavaがC ++とは非常に異なり、各アプリケーションが「マシン固有」であり、コードを変更せずに移植できない場合、またはコードが実際に移植可能でビルドされている場合に、スクリプトは、少なくとも1回コンパイルすることなく、新しいターゲットを管理します。」
クライム

14

それは単なる言語ではなく、ライブラリです。

JavaとC ++の両方がクロスプラットフォームライブラリを提供します。Javaはより豊富なセットを提供します。


2
Javaはデフォルトでより豊富なセットを提供します。C ++でも同じライブラリが見つかりますが、それらは標準ライブラリの一部ではなく、使用するライブラリを決める必要があります(特にインストールされていない場合は簡単ではありません)。
マーティンヨーク

Javaの標準ライブラリをC ++のライブラリの世界と比較することは、実際には有効な比較ではありません。Javaは、それぞれの標準ライブラリを比較する場合でも、それぞれのライブラリのユニバースを比較する場合でも、より豊富なセットを提供します。
アンディトーマス

3
間違いなくそれに反対します。Javaライブラリにあるものはすべて、一部のライブラリのC ++ですでに使用可能です。私はJavaがすべてを1か所に持っているという事実が好きですが、それがより豊かであると言うのは真実ではありません。たぶんあなたが探している形容詞は「より統合された」
マーティンヨーク

1
+1は再度投票します。ライブラリは移植性の最大の要因だと思います。C / C ++で作業していて、純粋な計算以外のことをしている場合、WindowsとUnixで根本的に異なり、Unixの異なるフレーバーで微妙に異なるライブラリ(特に、システムライブラリの一部)があります。それは移植を難しくします。Javaには基本的にそのような問題はありません。
トムアンダーソン

1
@Andy Thomas-Cramer:私は何も比較していません(あなたはそうです)。あなたの声明は不正確だと言っています。Javaの利点の1つ(そしてそのために私たち全員が気に入っています)は、すべての標準ライブラリが1か所にあることです。彼らがより豊かであると言うことは正確ではありません。
マーティンヨーク

7

違いは、Javaはどのプラットフォームで再コンパイルせずに実行されることです。各プラットフォームにC ++コンパイラを使用することは、まったく同じではありません。


6

「違いは...」で始まるすべての答え、または非常に似ているものはすべて基本的に間違っています(ごめんなさい、しかしそれは人生です)。実際には、2つの間に2つの異なる違いがあります。

1つ(多く言及されています)は、コンパイルされたJavaプログラムはJavaの準拠実装で実行できる(または最低限すべき)ため、コンパイルされた後でも、再コンパイルせずに1つのプラットフォームから別のプラットフォームにJavaプログラムを移動できます。C ++(少なくとも通常)では、ターゲットプラットフォームごとに再コンパイルが必要です。

もう1つは、正しく記述されたすべてのJavaが移植可能であることをJavaが保証する(少なくとも試行する)ということです。少なくとも理論的には、移植性のないコードを書くことはできません。

C ++では、移植性のない非常に多くのことができます。C ++標準には、移植性のない多くの事項(たとえば、実装定義の動作または未定義の動作が発生することを伝える)に関する「警告」が含まれていますが、必ずしもそれらを実行しようとするわけではありません。たとえば、PCIバスを使用するハードウェア用のオペレーティングシステムを作成する場合は、おそらくPCI構成メモリの読み取り/書き込みが必要になります。これは明らかに、PCIバスのないシステムには移植できませんが、PCIバスのあるハードウェア用のオペレーティングシステムを作成する場合は、ほとんど必要です。C ++は、明らかにポータブルではない場合でも許可します。


C ++はPCIバスやハードウェアについては何も知りません。
日光

もちろんそうではありません。これらはプラットフォーム固有のものであり、プラットフォーム固有のライブラリに含める必要があります。必要に応じてJavaがプラットフォーム固有のライブラリを持つことができるように。
11

1
@Nikko:それについて何も知りませんが、あなたがそれについて知っていることを使うことできます。
ジェリーコフィン

@jwenting:違いは、プラットフォーム固有のライブラリをC ++で記述できますが、通常 Javaで記述できないことです。
ジェリーコフィン

6

前提を誤解しています。JVMは、同じことが保証された標準の動作を提供するため、Java プログラムは非常に移植性があります。C ++プログラムは、実際のハードウェアにより近い標準化されていない環境を持っているため、プログラムは、intのサイズ、ワードアラインメントなど、さまざまなプラットフォーム固有の詳細を処理できる必要があります。

JVM自体はあまり移植性がありません。高性能のJVMを別のプラットフォームまたはCPUアーキテクチャに移植することは非常に困難な作業です。


その最後の文に+1!
ラーム

2

違いは、Java(略語ではない)プログラムは、JVMがインストールされた任意のコンピューターで実行できる形式で配布できることですが、C ++は通常、ソースコードとして配布されます。異なるプラットフォーム用の異なるバイナリの。


え?JVMをターゲットとするC ++コンパイラと、ネイティブコードをターゲットとするJavaコンパイラがあります。C ++プログラム、ソースコードまたはプラットフォーム固有のバイナリとして配布する必要があるというC ++言語仕様の特定のセクションを引用できますか?
ヨルグWミットタグ

そこで、私は答えを編集して、より明確でない言語を使用するようにしました。
コリン

2

Javaが移植性があると見なされる理由の1つは、算術式を評価する方法に関する特定のルールがあり、実装を他の方法で評価することを禁止していることです。ファッション。

たとえば、与えられた

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

thing1(2147483647)およびの値はthing2(1123456700,11234567.0f)、算術的に正しい値が2147483647Lおよび100.0であり、一部のプラットフォームでは数値的に不正確な結果を生成するコードが正しい生成コードよりも遅い場合でも、それぞれ-2147483649Lおよび99.9999923706054688である必要があります結果(一部の64ビットプラットフォームでは、(x + 1)の後にラッピング動作を強制するには追加の命令が必要になり、8x87プラットフォームでは1123456700の値を強制的に丸めるにはfloat単純なロードと比較して追加の命令が必要になります)拡張精度レジスタに直接)。


1
Javaには非常に正確な算術要件があり、もちろんプリミティブデータ型にはC ++と比較して特定のサイズとセマンティクスがあります。この日付に関するこれ以外の回答はありません。

@スノーマン:選択した特定の例はどうですか?個人的に言語を設計している場合(int)、最初の例の最初の例の(x+1)部分式float、2番目の例のxパラメータへのキャストを狭めることなく、どちらの例もJavaの値を返しませんでしたが、明らかに言語を設計しませんでした。
supercat 14年

理にかなっていると思います。どの言語にとっても重要なことは、明確に定義されたセマンティクスを持つことです。特定の言語設計の決定に同意するかどうかに関係なく、重要なことは、コードを見て、それどのように機能するかを知ることができることです。Javaは一般的にそれを行いますが、未定義の動作はほとんどありません。

1

サポートツールの作業量は実際に似ていますが、違いは他の場所にあります。プラットフォーム用にC ++プログラムをコンパイルしたら、別のプラットフォームで使用する場合は、再度コンパイルする必要があります。ただし、Javaプログラムがコンパイルされたら、再コンパイルすることなく、ランタイム環境を備えた他のプラットフォームに移動できます。


1

「移植性は神話ですか?」というタイトルに答えると、「移植性、JavaまたはC ++のどちらが優れているか」ではなく、部分的な移植性は可能ですが、完全な移植性は神話になります。

私が書くことを主張し、この質問に当てはまることは、開発者はもはやプログラミング言語だけでなく、完全なプログラミングフレームワークで作業しているということです。

これらのフレームワークには、ライブラリ、データベース、グラフィカルインターフェイスが含まれます。

どのプログラミング言語、またはどのプログラミングフレームワークがより移植性がありますか?

まあ、それはあなたのアプリに依存します。達成しようとしています。


1

事は「あなたは」あなたが上で動作するJavaコードの書き込みJREを書かないで任意の JREを。「あなたは」C ++コードを書くのですか可能で、変更を必要とします、それは別のプラットフォーム上でコンパイルする前に。


0

多くの人々は、「100%ポータブル」またはそのようなフレーズを言うとき、Javaの現実を忘れるか、考慮しません。

ほぼすべての主要な企業/ソフトウェアハウスには、過去に少なくとも1つの自家製Javaの実装があり、最近JREが関連付けられており、一部はまだそれを維持しています。たとえば、Microsoft、IBM、Appleなどはすべて、業界やそのような言語がどこに行くべきかについての自分の考えや考え

「ポータブル」はどうですか?あなたが向けるどこでもJRE。

これは、Sun / Oracleが何をしていたかを考慮していません。

移植性の点でJavaコードがCとC ++からそれほど遠くない理由の例は、GUIとグラフィカルサーバーです。Appleは独自のJREのGUIフレームワークの非標準の実装を持っていました。その結果、 Appleマシン用のJavaを使用してGUIを作成/移植したい人には頭痛と二重の働きがあり、基本的にQuartzに対処せざるを得ませんでした(「レバレッジ」と高レベル言語の点ではどうですか)。

時々、最も一般的に使用される単語でさえ、人々が通常与える意味を実際に反映していないことがあります。Javaの世界での「移植性」という用語は、常識では「展望」に似ています。(少なくともJavaが生まれた時点で)他の言語ではなくJavaを採用する場合、商業的および財務的な面でより良い見通しがあります。 「コンピューター」と見なすことができます)、コードベースはそのまま移植できる可能性が高いため、プログラムを移植するために必要なリソースが少なくなります。つまり、リソースがお金、時間、または人的資源であっても、他のテクノロジーと比較したしきい値であり、それがJavaの目的であり、そのしきい値を下げています。

もちろん、Javaの前提を受け入れる場合、つまり、ガベージコレクションを備えた仮想マシン、つまりネイティブ言語と比較してより多くのリソースを消費すること、つまりCPUまたはサーバーファームから最大限の圧縮を行いたい場合、リソースが本当に不足しているか、会社が本当に小規模でない限り、Javaを採用できるとは思わないでください。

コードや機能の行ごとに1つのバージョンのみを含む単一の非自明なJavaアプリケーションを見つける必要があり(プラットフォーム固有のものもありません)、すべての主要なJRE間で100%移植可能です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.