Warum ist Java portabler als andere Sprachen wie C ++?

16

Was ist der Unterschied zwischen "Schreiben einer spezifischen JRE für jede Plattform" für Java-Entwickler und "Schreiben eines C ++ - Compilers für jede Plattform" für C ++ - Entwickler?

user967316
quelle

Antworten:

33

Java wird einmal kompiliert und überall ausgeführt. C ++ wird irgendwo einmal kompiliert.

Pubby
quelle
3
Nun, Sie haben offensichtlich nicht viel Erfahrung mit der GUI-Entwicklung. (Warten auf Qt ...)
27
Wer behauptet, C ++ sei "irgendwo einmal kompilieren", musste noch nie ein C ++ - Programm
portieren
7
Ich stimme BlueRaja zu. Das Portieren eines C ++ - Programms bedeutet so viel mehr als das Portieren des Compilers. C ++ ist am weitesten verbreitet in kritischen Umgebungen, in denen Dinge wie die Größe eines Int oder die Implementierung eines Dateisystems einen so großen Unterschied machen können. Portierung bedeutet NICHT einfach Neukompilieren.
Rahmu
8
@ Pubby8 nein, Portabilitätsprobleme ergeben sich auch aus ziemlich normalem Code, der nicht portable Annahmen macht , wie Annahmen über Endianness (was Sie allerdings auch in Java leiden können), Ausrichtung und Größe grundlegender Typen.
R. Martinho Fernandes
5
Einmal schreiben, überall debuggen.
Bhagyas
25

"Schreiben einer spezifischen JRE für jede Plattform" ist etwas, das Sie nicht jedes Mal tun. Sie müssen die JRE nur einmal auf eine neue Plattform portieren. Diese Aufgabe wird in der Regel vom Hauptbetreuer / den Entwicklern des Programms und / oder der Plattform ausgeführt. Bei der Entscheidung, wer und wie die JRE portiert werden soll, können viele Faktoren ins Spiel kommen. Unter anderem hängt es von der Lizenz ab, unter der es veröffentlicht wurde (ich habe gehört, Java ist Open Source, also kann es wohl jeder machen). Die witzige Anekdote, Steve Jobs, machte vor etwa einem Jahr eine große Sache, weil er sich nicht um die Portierung von Java auf Mac kümmern wollte .

Es geht nicht darum, wie oder wer die JRE portiert, sondern darum, dass nach der Portierung jede Java-Anwendung theoretisch problemlos auf der neuen Maschine ausgeführt werden sollte. In diesem Sinne bildet die JRE eine Abstraktionsschicht, die die Maschine vollständig verbirgt und eine einfache Portierung ermöglicht.

Die Realität sieht jedoch nicht immer so aus. Ich werde nicht so weit gehen, Portabilität als "Mythos" zu bezeichnen, aber es ist wahr, dass es nicht so perfekt ist. Beispielsweise hat Java ein Paket namens JNI"Write Once Run Anywhere", mit dem native Aufrufe unter Umgehung der JRE gesendet werden können, wodurch die perfekte nahtlose Portabilität verhindert wird, die Java-Fans gerne als "Write Once Run Anywhere" bezeichnen.

Wie in den Kommentaren erwähnt, unterscheidet sich C ++ hinsichtlich der Portabilität. Einerseits ist es eine kompilierte Sprache, und diese Binärdateien sind fast immer plattformspezifisch. Daher werden ausführbare C ++ - Dateien (anders als Java) niemals portierbar sein. Andererseits kann es manchmal ausreichen, den Compiler zu portieren. Die Community hat festgestellt, dass durch Portierung des Compilers sowie einiger Kernbibliotheken der Sprache Quellcodes (und nicht Binärdateien) portierbar sein könnten.

C ++ wird jedoch häufig in kritischen Systemen wie Compilern, Kerneln, Echtzeitsystemen, eingebetteten Systemen usw. verwendet. Ein Aspekt von C ++ auf "niedriger Ebene" ist nicht zu übersehen, wenn es um Portabilität geht.

rahmu
quelle
4
Portabilität ist kein Mythos. Perfekte Portabilität ist.
Malcolm
"Hier unterscheidet sich Java stark von C ++, wo jede Anwendung" maschinenspezifisch "ist und nicht portiert werden kann, ohne den Code zu ändern." Das stimmt nicht, es kommt auf die Abhängigkeiten an. Wenn Sie nur die Standardbibliothek und Bibliotheken mit portierbaren Quellen für Ihre Ziele verwenden, codieren Sie einmal und kompilieren auf jedem Ziel. Wenn Sie etwas codieren, das portiert werden kann, ohne den Code in C ++ zu ändern, müssen Sie möglicherweise nur die Erstellungsskripten ändern. Das stimmt nicht in allen Fällen.
Klaim
Vergessen wir nicht, dass C ++ sowohl als High-Level- als auch als Low-Level-Sprache verwendet werden kann. In Programmen, in denen sich ein 32-Bit-Int von einem 64-Bit-Int stark unterscheidet, wird viel C ++ - Code verwendet. High-Level wird natürlich immer tragbar sein. Aber es ist weit von einer C ++
rahmu
Ich glaube, Sie haben das, was ich sage, vielleicht falsch verstanden: Sie können korrektes C ++ mit int oder einem beliebigen Standardtyp schreiben, ohne sich um einfache Dinge zu kümmern. Schauen Sie sich nur die Boost-Bibliotheken an, die meisten sind nur Code auf hoher Ebene, und das gilt für viele C ++ - Open-Source-Projekte. Sie können auf "low level" gehen, und wenn Sie dies tun, können Sie auch einen bestimmten Code vermeiden, bis Sie eine plattformspezifische API verwenden müssen. Aber wenn Sie das nicht müssen, können Sie C ++ schreiben, das überall funktioniert. Die Abhängigkeit von der Plattform kann vermieden werden und liegt häufig im Bibliothekscode vor.
Klaim
Nur um sicherzugehen, dass ich klar bin: Ich sage nicht, dass der gesamte C ++ - Code portierbar ist, ich sage, dass Ihre Aussage so wie sie ist falsch ist. Vielleicht möchten Sie das Problem folgendermaßen beheben: "Hier unterscheidet sich Java stark von C ++, wo jede Anwendung" maschinenspezifisch "ist und nicht portiert werden kann, ohne den Code zu ändern oder wenn der Code wirklich portierbar und kompilierbar ist Skripte verwalten das neue Ziel ohne mindestens eine Kompilierung. "
Klaim,
14

Es ist nicht nur die Sprache - es sind die Bibliotheken.

Sowohl Java als auch C ++ bieten plattformübergreifende Bibliotheken. Java bietet eine reichhaltigere Auswahl.

Andy Thomas
quelle
2
Java bietet standardmäßig eine umfangreichere Auswahl. Dieselben Bibliotheken sind für C ++ verfügbar, sie gehören jedoch nicht zu den Standardbibliotheken, und Sie müssen nur entscheiden, welche verwendet werden sollen (was insbesondere dann nicht trivial ist, wenn sie nicht installiert sind).
Martin York
Der Vergleich der Standardbibliotheken von Java mit dem Universum von Bibliotheken für C ++ ist kein wirklich gültiger Vergleich. Java bietet eine umfangreichere Auswahl, unabhängig davon, ob Sie die Standardbibliotheken der einzelnen Bibliotheken oder das Universum der Bibliotheken der einzelnen Bibliotheken vergleichen.
Andy Thomas
3
Dem kann man definitiv nicht zustimmen. Alles, was in der Java-Bibliothek verfügbar ist, steht C ++ bereits in einigen Bibliotheken zur Verfügung. Ich mag die Tatsache, dass Java alles an einem Ort hat, aber zu sagen, dass es reicher ist, ist einfach nicht wahr. Vielleicht ist das gesuchte Adjektiv "integrierter"
Martin York
1
+1 würde wieder stimmen. Ich denke, die Bibliotheken sind der größte Faktor für die Portabilität. Wenn Sie in C / C ++ arbeiten und etwas anderes als reine Berechnungen ausführen, gibt es Bibliotheken (insbesondere Teile der Systembibliothek), die sich zwischen Windows und Unix grundlegend und zwischen verschiedenen Unix-Versionen geringfügig unterscheiden. Das macht das Portieren schwer. Java hat dieses Problem im Grunde nicht.
Tom Anderson
1
@ Andy Thomas-Cramer: Ich vergleiche nichts (du scheinst es zu sein). Ich sage, Ihre Aussage ist falsch. Einer der Vorteile von Java (und wir alle lieben es dafür) sind alle Standardbibliotheken an einem Ort. Zu sagen, dass sie reicher sind, ist einfach nicht richtig.
Martin York
7

Der Unterschied besteht darin, dass Java auf jeder Plattform ausgeführt werden kann, ohne dass eine Neukompilierung erforderlich ist. Einen C ++ - Compiler für jede Plattform zu haben, ist überhaupt nicht dasselbe.

Highland Mark
quelle
6

Alle Antworten, die mit "Der Unterschied ist ..." oder etwas sehr Ähnlichem beginnen, sind grundsätzlich falsch (Entschuldigung, aber so ist das Leben). Es gibt wirklich zwei getrennte Unterschiede zwischen den beiden.

Eines (was schon oft erwähnt wurde) ist, dass ein kompiliertes Java-Programm auf jeder kompatiblen Java-Implementierung ausgeführt werden kann (oder sollte), sodass Sie ein Java-Programm auch nach dem Kompilieren von einer Plattform auf eine andere verschieben können, ohne es erneut zu kompilieren . C ++ erfordert (zumindest normalerweise) eine Neukompilierung für jede Zielplattform.

Das andere ist, dass Java (zumindest Versuche) sicherstellt, dass alles korrekt geschriebene Java portierbar ist. Zumindest theoretisch sollten Sie keinen Code schreiben können, der nicht portierbar ist.

Mit C ++ können Sie einige Dinge tun, die nicht portabel sind. Der C ++ - Standard enthält "Warnungen" zu vielen Dingen, die nicht portierbar sind (z. B. zu dem Hinweis, dass Sie implementierungsdefiniertes oder undefiniertes Verhalten erhalten), aber er versucht nicht unbedingt, Sie davon abzuhalten, dies überhaupt zu tun . Wenn Sie beispielsweise ein Betriebssystem für Hardware schreiben möchten, die einen PCI-Bus verwendet, müssen Sie wahrscheinlich den PCI-Konfigurationsspeicher lesen / schreiben. Dies ist natürlich nicht auf Systeme ohne PCI-Bus übertragbar, aber wenn Sie ein Betriebssystem für Hardware mit einem PCI-Bus schreiben, ist dies ziemlich notwendig. C ++ erlaubt es, obwohl es offensichtlich nicht portabel ist.

Jerry Sarg
quelle
C ++ kennt sich jedoch weder mit PCI-Bus noch mit Hardware aus.
Nikko
Natürlich nicht, das sind plattformspezifische Dinge, die in plattformspezifischen Bibliotheken enthalten sein müssen. Ebenso wie Java bei Bedarf plattformspezifische Bibliotheken haben kann.
28.
1
@ Nikko: Es weiß nichts darüber, aber es ermöglicht Ihnen, das zu verwenden, was Sie darüber wissen.
Jerry Coffin
@jwenting: Der Unterschied besteht darin, dass Sie die plattformspezifischen Bibliotheken in C ++ schreiben können, im Allgemeinen jedoch nicht in Java.
Jerry Coffin
6

Sie haben die Räumlichkeiten falsch verstanden. Java- Programme sind sehr portabel, da die JVM ein Standardverhalten bietet, das garantiert gleich ist. C ++ - Programme haben eine weniger standardisierte Umgebung, die näher an der tatsächlichen Hardware liegt. Daher muss das Programm in der Lage sein, die verschiedenen plattformspezifischen Details zu verarbeiten - wie Größe eines Int, Wortausrichtung usw. usw. usw.

Die JVM selbst ist nicht sehr portabel. Es ist eine Herkulesaufgabe, eine leistungsstarke JVM auf eine andere Plattform oder CPU-Architektur zu portieren.


quelle
+1 für den letzten Satz!
Rahmu
2

Der Unterschied besteht darin, dass Java-Programme (kein Akronym) in einer Form verteilt werden können, die auf jedem Computer mit installierter JVM ausgeführt werden kann. C ++ wird jedoch normalerweise entweder als Quellcode, der sehr benutzerfreundlich ist, oder als Bündel von Programmen verteilt von verschiedenen Binärdateien für verschiedene Plattformen.

Colin
quelle
Huh? Es gibt C ++ - Compiler, die auf die JVM abzielen, und es gibt Java-Compiler, die auf systemeigenen Code abzielen. Können Sie den bestimmten Abschnitt der Sprache C ++ Spezifikation zitieren , die besagt , dass C ++ Programme müssen entweder als Quellcode oder plattformspezifische Binärdateien verteilt werden?
Jörg W Mittag
Dort habe ich meine Antwort bearbeitet, um eine weniger eindeutige Sprache zu verwenden
Colin
2

Einer der Gründe, warum Java als portabel gilt, besteht darin, dass es spezifische Regeln für die Bewertung von arithmetischen Ausdrücken gibt und Implementierungen davon abhält, diese auf andere Weise zu bewerten, selbst wenn eine Bewertung in der vorgeschriebenen Weise einen langsameren Code erfordern würde als eine genauere Bewertung Mode.

Zum Beispiel gegeben

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

Die Werte von thing1(2147483647)und thing2(1123456700,11234567.0f)müssen -2147483649L bzw. 99.9999923706054688 sein, obwohl die arithmetisch korrekten Werte 2147483647L und 100.0 sind und obwohl auf einigen Plattformen der Code zum Generieren der numerisch falschen Ergebnisse langsamer als der Code zum Generieren der korrekten Werte ist Ergebnisse (auf einigen 64-Bit-Plattformen würde das Erzwingen des Umbruchverhaltens nach (x + 1) einen zusätzlichen Befehl erfordern, und auf der 8x87-Plattform würde das Erzwingen der Rundung des Werts von 1123456700 auf a floateinen zusätzlichen Befehl erfordern, verglichen mit dem einfachen Laden es direkt zu einem Register mit erweiterter Genauigkeit).

Superkatze
quelle
1
Diesmal eine neue Antwort auf eine alte Frage, die tatsächlich einen Mehrwert bietet: Java hat sehr genaue arithmetische Anforderungen, und natürlich haben die primitiven Datentypen im Vergleich zu C ++ spezifische Größen und Semantiken. Keine andere Antwort erwähnt dies zum jetzigen Zeitpunkt.
@Schneemann: Wie gefallen Ihnen die ausgewählten Beispiele? Wenn ich persönlich eine Sprache entworfen hätte, hätte ich weder das eine noch das andere Beispiel dazu gebracht, den Wert von Java zurückzugeben, ohne Casts (int)für den (x+1)Unterausdruck des ersten Beispiels auf floatden xParameter des zweiten Beispiels einzuengen, aber natürlich habe ich die Sprache nicht entworfen .
Supercat
Ich denke, sie machen Sinn. Für jede Sprache ist es wichtig, eine klar definierte Semantik zu haben. Unabhängig davon, ob man mit einer bestimmten Entscheidung zum Sprachdesign einverstanden ist, ist es wichtig, sich den Code anzusehen und zu wissen, wie er funktioniert. Java tut dies im Allgemeinen mit wenigen Fällen von undefiniertem Verhalten.
1

Der Arbeitsaufwand für die Hilfsmittel ist in der Tat ähnlich, der Unterschied liegt woanders. Sobald ein C ++ - Programm für eine Plattform kompiliert wurde, müssen Sie es erneut kompilieren, wenn Sie es auf einer anderen Plattform verwenden möchten. Wenn ein Java-Programm kompiliert wurde, können Sie es auf eine andere Plattform mit einer Laufzeitumgebung verschieben, ohne es erneut kompilieren zu müssen.


quelle
1

Bei der Beantwortung des Titels "Ist Portabilität ein Mythos?" Anstelle von "Was ist besser an Portabilität, Java oder C ++?" Werde ich sagen, dass teilweise Portabilität möglich ist, aber vollständige Portabilität ist ein Mythos.

Ich bestehe darauf, zu schreiben, und das gilt auch für diese Frage: Entwickler arbeiten nicht mehr nur mit Programmiersprachen, sondern mit vollständigen Programmierframeworks.

Zu diesen Frameworks gehören Bibliotheken, Datenbanken und grafische Oberflächen.

Welche Programmiersprache oder welches Programmierframework ist portabler?

Nun, es kommt darauf an, welche App du verwendest. versucht zu erreichen.

umlcat
quelle
1

Die Sache ist, dass "Sie" nicht die JRE schreiben, sondern den Java-Code, der auf einer JRE ausgeführt wird. „Sie“ schreiben Sie den C ++ Code, können Änderungen erfordern Sie , bevor es auf einer anderen Plattform kompilieren.

James Anderson
quelle
0

Viele Leute vergessen oder berücksichtigen die Realität von Java nicht, wenn sie sagen, dass "es 100% portabel ist" oder solche Ausdrücke.

So gut wie alle großen Unternehmen / Softwarehäuser hatten in der jüngeren Vergangenheit mindestens eine hausgemachte Java-Implementierung mit einer zugehörigen JRE und einige haben diese immer noch gepflegt. Microsoft, IBM und Apple hatten beispielsweise alle ihre eigene Java-Version, die ihre eigene Version widerspiegelte Eigene Ideen und Überlegungen, wohin die Branche und solche Sprache gehen soll.

Wie ist das für "tragbar"? Ein JRE, wo immer Sie abbiegen.

Dabei spielt es keine Rolle, was Sun / Oracle getan hat.

Ein Beispiel dafür, warum Java-Code in Bezug auf die Portabilität nicht wirklich weit von C und C ++ entfernt ist, sind die GUIs und die Grafikserver. Apple hatte eine nicht standardisierte Implementierung des GUI-Frameworks für sein eigenes JRE. Infolgedessen gab es viele Kopfzerbrechen und Doppelarbeit für alle, die eine GUI mit Java für Apple-Maschinen erstellen / portieren wollten und im Grunde gezwungen waren, mit Quarz umzugehen (wie ist das in Bezug auf "Hebel" und Hochsprachen?).

Manchmal spiegeln sogar die am häufigsten verwendeten Wörter nicht wirklich die Bedeutung wider, die die Leute ihnen normalerweise geben. Für mich ist der Begriff "Portabilität" in der Java-Welt eher wie "Ausblick" im gesunden Menschenverstand. In wirtschaftlicher und finanzieller Hinsicht gibt es einen besseren Ausblick für Sie, wenn Sie Java anstelle anderer Sprachen einsetzen (zumindest zu dem Zeitpunkt, als Java geboren wurde), weil Sie bereits eine Menge Arbeit auf einer Seite erledigt haben (Sie erhalten eine JRE für alles Das kann als "Computer" bezeichnet werden. Ihre Codebasis ist wahrscheinlich portabel. Sie benötigen weniger Ressourcen, um Ihr Programm zu portieren. Es spielt keine Rolle, ob es sich um Geld, Zeit oder Arbeitskräfte handelt. Es ist eine geringere Schwelle im Vergleich zu anderen Technologien und das ist, wofür Java ist, es senkt diese Schwelle.

Dies gilt natürlich, wenn Sie die Voraussetzungen von Java akzeptieren, dh eine virtuelle Maschine mit Garbage Collection, die im Vergleich zu Muttersprachen mehr Ressourcen verbraucht, wenn Sie wirklich das Maximum aus Ihrer CPU oder Serverfarm herausholen möchten Denken Sie nicht, dass Sie Java einsetzen können, es sei denn, Sie haben nur wenig Ressourcen oder Ihr Unternehmen ist wirklich klein.

Ich muss immer noch eine einzige nicht-triviale Java-Anwendung finden, die nur eine Version für jede Code- oder Funktionszeile enthält (auch bekannt als ohne plattformspezifische Komponenten) und die zu 100% auf alle wichtigen JREs portierbar ist.

user2485710
quelle