Perché Java è considerato più portatile di altri linguaggi come il C ++?


16

Cosa differisce tra "scrivere un JRE specifico per ogni piattaforma" per gli sviluppatori Java e "scrivere un compilatore C ++ per ogni piattaforma" per quelli C ++?

Risposte:


33

Java viene compilato una volta eseguito ovunque. C ++ viene scritto una volta compilato ovunque.


3
Beh, ovviamente non hai avuto molta esperienza con lo sviluppo della GUI. (Aspettando Qt ...)

27
Chiunque sostenga che il C ++ sia "scrivere una volta compilato ovunque" non ha mai dovuto eseguire il porting di un programma C ++ ...
BlueRaja - Danny Pflughoeft

7
Sono d'accordo con BlueRaja. Il porting di un programma C ++ significa molto più che il porting del compilatore. Il C ++ è ampiamente presente in ambienti critici in cui cose come la dimensione di un int o l'implementazione di un file system possono fare una differenza così grande. Porting NON significa semplicemente ricompilare.
Rahmu,

8
@ Pubby8 no, anche i problemi di portabilità derivano da un codice piuttosto standard che fa ipotesi non portabili , come ipotesi sull'endianness (che ti dispiace, puoi anche soffrire in Java), allineamento e dimensione dei tipi fondamentali.
R. Martinho Fernandes,

5
Scrivi una volta, esegui il debug ovunque.
bhagyas,

25

"scrivere un JRE specifico per ogni piattaforma" non è qualcosa che fai ogni volta. Il porting di JRE su una nuova piattaforma è qualcosa che devi fare solo una volta. Questo compito viene generalmente svolto dal manutentore principale / dagli sviluppatori del programma e / o della piattaforma. Molti fattori possono entrare in gioco quando si decide chi e come il JRE verrebbe portato. Tra le altre cose, dipende dalla licenza con cui è pubblicato (ho sentito che Java è Open Source, quindi immagino che chiunque possa farlo). Un aneddoto divertente, Steve Jobs ha fatto molto per non voler occuparsi del porting di Java su Mac , circa un anno fa.

Il punto non è come o chi porta il JRE, ma il fatto che una volta effettuato il porting, ogni applicazione Java dovrebbe ora teoricamente funzionare facilmente sulla nuova macchina. In tal senso, JRE forma uno strato di astrazione, nascondendo completamente la macchina, consentendo un facile porting.

Tuttavia, la realtà non è sempre abbastanza così. Non andrò fino a chiamare la portabilità un "mito", ma è vero che non è così perfetto. Ad esempio, Java ha un pacchetto chiamato JNIche consente l'invio di chiamate native, bypassando JRE, impedendo così la perfetta portabilità senza soluzione di continuità, ciò che i fan di Java amano chiamare "Scrivi una volta eseguito ovunque".

Come menzionato nei commenti, l'approccio del C ++ alla portabilità è diverso. Da un lato, è un linguaggio compilato e quei binari sono quasi sempre specifici della piattaforma. Quindi gli eseguibili c ++ non saranno mai portatili (a differenza di Java). D'altra parte, il porting del compilatore può talvolta essere sufficiente. La comunità ha scoperto che eseguendo il porting del compilatore e di alcune librerie di base del linguaggio, i codici sorgente (e non i binari) potrebbero essere portatili.

Tuttavia, il C ++ è ampiamente usato in sistemi critici come compilatori, kernel, sistemi in tempo reale, sistemi integrati, ... C'è un aspetto "di basso livello" del C ++ che non può essere trascurato, quando si parla di portabilità.


4
La portabilità non è un mito. La portabilità perfetta è.
Malcolm,

"il suo è dove Java è molto diverso dal C ++, dove ogni applicazione è" specifica della macchina "e non può essere trasferita senza modificare il codice." Questo non è vero, dipende dalle dipendenze. Se si utilizzano solo le librerie standard e le librerie con sorgenti portatili per i target, si codifica una volta e si compila su ciascun target. Se si codifica qualcosa che può essere portato senza modificare il codice in C ++, l'unica cosa che potrebbe essere necessario modificare sono gli script di compilazione. Questo non è nemmeno vero in tutti i casi.
Klaim,

Non dimentichiamo che il C ++ può essere usato sia come linguaggio di alto livello che di basso livello. Molto codice C ++ viene utilizzato in programmi in cui un int a 32 bit è molto diverso da un int a 64 bit. L'alto livello sarà sempre portatile, ovviamente. Ma è tutt'altro che una generalizzazione in C ++
rahmu,

Penso che potresti aver frainteso quello che sto dicendo: puoi scrivere C ++ corretto con int o qualsiasi tipo standard senza preoccuparti di cose di basso livello. Dai un'occhiata alle librerie boost, la maggior parte sono solo codici di alto livello, ed è vero per molti progetti open source C ++. Puoi "passare" a basso livello e, se lo fai, puoi anche evitare qualsiasi codice specifico fino a quando non è necessario utilizzare API specifiche della piattaforma. Ma se non è necessario, puoi scrivere C ++ che funziona ovunque. La dipendenza dalla piattaforma può essere evitata e spesso è nel codice della libreria.
Klaim,

Solo per essere sicuro di essere chiaro: non dico che tutto il codice C ++ sia portatile, sto dicendo che così com'è, la tua affermazione è sbagliata. Potresti volerlo risolvere con qualcosa del tipo: "Qui Java è molto diverso dal C ++, dove ogni applicazione è" specifica per la macchina "e non può essere trasferita senza modificare il codice o, se il codice è davvero portatile e la build gli script gestiscono il nuovo target, senza almeno una compilation ".
Klaim,

14

Non è solo la lingua, sono le biblioteche.

Sia Java che C ++ forniscono librerie multipiattaforma. Java fornisce un set più ricco.


2
Java fornisce un set più ricco per impostazione predefinita. Le stesse librerie possono essere trovate per C ++ e non fanno semplicemente parte delle librerie standard e devi solo decidere quali utilizzare (che non è banale soprattutto se non sono installate).
Martin York,

Confrontare le librerie standard di Java con l'universo delle librerie per C ++ non è in realtà un confronto valido. Java fornisce un set più ricco, sia che si stiano confrontando le librerie standard di ciascuna, sia che si stia confrontando l'universo delle librerie di ciascuna.
Andy Thomas,

3
Decisamente in disaccordo con quello. Tutto ciò che è disponibile nella libreria Java è già disponibile per l'uso da C ++ in alcune librerie. Mi piace il fatto che Java abbia tutto in un unico posto, ma dire che è più ricco non è vero. Forse l'aggettivo che stai cercando è `più integrato '
Martin York,

1
+1 avrebbe votato di nuovo. Penso che le biblioteche siano il principale fattore di portabilità. Se stai lavorando in C / C ++ e stai facendo qualcosa di diverso dal puro calcolo, ci saranno librerie (in particolare, parti della libreria di sistema) che sono radicalmente diverse tra Windows e Unix e leggermente diverse tra le diverse versioni di Unix. Questo rende difficile il porting. Java sostanzialmente non ha questo problema.
Tom Anderson,

1
@Andy Thomas-Cramer: non sto confrontando nulla (sembra che tu sia). Sto dicendo che la tua affermazione non è precisa. Uno dei vantaggi di Java (e tutti noi lo adoriamo per questo) sono tutte le librerie standard in un unico posto. Dire che sono più ricchi non è proprio preciso.
Martin York,

7

La differenza è che Java verrà eseguito su qualsiasi piattaforma senza ricompilazione. Avere un compilatore C ++ per ogni piattaforma non è affatto lo stesso.


6

Tutte le risposte che iniziano con "La differenza è ...", o qualcosa di molto simile, sono fondamentalmente sbagliate (scusate, ma tale è la vita). Ci sono davvero due differenze separate tra i due.

Uno (che è stato menzionato molto) è che un programma Java compilato può (o almeno dovrebbe) essere eseguito su qualsiasi implementazione conforme di Java, quindi anche dopo essere stato compilato, puoi comunque spostare un programma Java da una piattaforma all'altra senza ricompilare . Il C ++ (almeno normalmente) richiede una ricompilazione per ciascuna piattaforma di destinazione.

L'altro è che Java (almeno tenta di) assicurare che tutte le Java correttamente scritte siano portatili. Almeno in teoria, non dovresti essere in grado di scrivere alcun codice che non sia portatile.

Il C ++ ti consente di fare alcune cose che non sono portatili. Lo standard C ++ contiene "avvertimenti" su molte cose che non sono portatili (ad esempio, ti dicono che otterrai un comportamento definito dall'implementazione o un comportamento indefinito), ma non cerca necessariamente di impedirti di farlo . Ad esempio, se si desidera scrivere un sistema operativo per l'hardware che utilizza un bus PCI, probabilmente sarà necessario leggere / scrivere la memoria di configurazione PCI. Questo ovviamente non sarà portatile per i sistemi senza un bus PCI, ma se stai scrivendo un sistema operativo per hardware con un bus PCI, è praticamente necessario. Il C ++ lo consente anche se ovviamente non sarà portatile.


Tuttavia, C ++ non sa nulla del bus PCI né dell'hardware.
Nikko,

ovviamente no, quelle sono cose specifiche della piattaforma che dovranno essere incluse nelle librerie specifiche della piattaforma. Proprio come Java può avere librerie specifiche della piattaforma, se necessario.
jwenting,

1
@Nikko: non ne sa nulla, ma ti permette di usare ciò che sai al riguardo.
Jerry Coffin,

@jwenting: la differenza è che puoi scrivere le librerie specifiche della piattaforma in C ++, ma generalmente non puoi scriverle in Java.
Jerry Coffin,

6

Hai frainteso le premesse. Programmi Java sono molto portabili, poiché JVM offre un comportamento standard garantito come lo stesso. I programmi C ++ hanno un ambiente meno standardizzato più vicino all'hardware reale, quindi il programma deve essere in grado di gestire i vari dettagli specifici della piattaforma - come le dimensioni di un int, l'allineamento delle parole ecc. Ecc. Ecc.

La JVM stessa non è molto portatile. È un compito erculeo portare una JVM ad alte prestazioni su un'altra piattaforma o architettura CPU.


+1 per l'ultima frase!
Rahmu,

2

La differenza è che i programmi Java (non è un acronimo) possono essere distribuiti in una forma che può essere eseguita su qualsiasi computer con una JVM installata, ma C ++ è normalmente distribuito come codice sorgente, che è molto ostile all'utente o come un gruppo di binari diversi per piattaforme diverse.


Eh? Esistono compilatori C ++ che hanno come target la JVM e ci sono compilatori Java che hanno come target il codice nativo. Puoi citare la sezione specifica della specifica del linguaggio C ++ che dice che i programmi C ++ devono essere distribuiti come codice sorgente o binari specifici della piattaforma?
Jörg W Mittag,

Lì, ho modificato la mia risposta per usare un linguaggio meno definitivo
Colin,

2

Uno dei motivi per cui Java è considerato portatile è che ha regole specifiche su come le espressioni aritmetiche devono essere valutate e proibisce alle implementazioni di valutarle in altro modo, anche quando valutarle nel modo richiesto richiederebbe un codice più lento rispetto a valutarle in modo più accurato moda.

Ad esempio, dato

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

I valori di thing1(2147483647)e thing2(1123456700,11234567.0f)devono essere -2147483649L e 99.9999923706054688, rispettivamente, anche se i valori aritmeticamente corretti sarebbero 2147483647L e 100.0, e anche se su alcune piattaforme il codice per generare risultati numericamente errati sarebbe più lento del codice per generare il corretto risultati (su alcune piattaforme a 64 bit, forzare il comportamento di wrapping dopo (x + 1) richiederebbe un'istruzione aggiuntiva, e sulla piattaforma 8x87, forzare il valore di 1123456700 per essere arrotondato a floatrichiederebbe un'istruzione aggiuntiva rispetto al semplice caricamento direttamente a un registro di precisione esteso).


1
Per una volta una nuova risposta a una vecchia domanda che aggiunge effettivamente qualcosa di valore: Java ha requisiti aritmetici molto precisi e, naturalmente, i tipi di dati primitivi hanno dimensioni e semantica specifiche rispetto al C ++. Nessun'altra risposta a partire da questa data menziona questo.

@Snowman: Ti piacciono gli esempi particolari scelti? Personalmente se stavo progettando un linguaggio non avrei fatto in modo che nessuno dei due esempi restituisse il valore di Java senza l'uso di restringere i cast (int)per la (x+1)sottoespressione del primo esempio nel primo esempio, al parametro floatdel secondo esempio x, ma ovviamente non ho progettato il linguaggio .
supercat

Penso che abbiano un senso. L'importante per qualsiasi lingua è avere una semantica ben definita. Indipendentemente dal fatto che si sia d'accordo con una determinata decisione di progettazione del linguaggio, l'importante è poter guardare il codice e sapere come funziona. Java generalmente lo fa, con pochi casi di comportamento indefinito.

1

La quantità di lavoro per gli strumenti di supporto è davvero simile, la differenza sta altrove. Una volta che un programma C ++ è stato compilato per una piattaforma, è necessario compilarlo di nuovo se si desidera utilizzarlo su una piattaforma diversa. Tuttavia, quando è stato compilato un programma java, è possibile spostarlo su qualsiasi altra piattaforma con un ambiente di runtime senza doverlo ricompilare.


1

Rispondendo al titolo "La portabilità è un mito?", Invece di "Quale è meglio la portabilità, Java o C ++", dirò che la portabilità parziale è possibile, ma la portabilità completa è un mito.

Qualcosa che insisto per scrivere, e si applica a questa domanda, è che gli sviluppatori non lavorano più solo con linguaggi di programmazione, ma con quadri di programmazione completi.

E quei framework, includono librerie, database, interfacce grafiche.

Quale linguaggio di programmazione o quale framework di programmazione è più portatile?

Bene, dipende da quale sia la tua app. sta cercando di raggiungere.


1

Il fatto è "tu" non scrivere il JRE, scrivi il codice Java che gira su qualsiasi JRE. "Tu" scrivi il codice C ++ che può richiedere modifiche da parte tua prima che venga compilato su un'altra piattaforma.


0

Molte persone dimenticano o non tengono conto della realtà di Java quando affermano che "è portatile al 100%" o frasi del genere.

Praticamente tutte le principali società di software / società avevano almeno 1 implementazione fatta in casa di Java con un JRE associato nel recente passato e alcuni lo mantengono ancora, Microsoft, IBM e Apple per esempio tutti avevano la propria versione di Java che rifletteva il loro proprie idee e pensieri su dove l'industria e tale linguaggio dovrebbero andare.

Come è "portatile"? Un JRE ovunque ti giri.

E questo è senza considerare cosa stava facendo Sun / Oracle.

Un esempio del perché il codice Java non è davvero lontano da C e C ++ in termini di portabilità sono le GUI e i server grafici, Apple ha avuto un'implementazione non standard del framework GUI per il proprio JRE, di conseguenza ci sono stati molti mal di testa e doppio lavoro per chiunque volesse creare / portare una GUI usando Java per macchine Apple e furono fondamentalmente costretti a gestire Quartz (com'è in termini di "leva" e linguaggi di alto livello?).

A volte anche le parole usate più comunemente non riflettono realmente il significato che le persone di solito danno loro, per me il termine "portabilità" nel mondo Java è più simile a "visione" nel senso comune; in termini commerciali e finanziari le prospettive sono migliori per te se adotti Java piuttosto che altre lingue (almeno al momento in cui Java è nato) perché hai già molto lavoro fatto da una parte (ottieni un JRE su qualsiasi cosa che può essere considerato un "computer") e la tua base di codice è probabile che sia portatile così com'è, hai bisogno di meno risorse per portare il tuo programma, tutto qui, indipendentemente dal fatto che detta risorsa sia denaro, tempo o manodopera non importa, è inferiore soglia rispetto ad altre tecnologie ed è a questo che serve Java, sta abbassando quella soglia.

Naturalmente questo è vero se si accettano le premesse di Java, il che significa una macchina virtuale con Garbage Collection, il che significa che consuma più risorse rispetto alle lingue native, se si desidera davvero ottenere il massimo dalla propria CPU o server farm I non pensare che puoi adottare Java a meno che tu non abbia risorse limitate o la tua azienda sia davvero piccola.

Devo ancora trovare un'unica applicazione Java non banale che contenga solo 1 versione per ogni riga di codice o funzionalità (ovvero senza elementi specifici della piattaforma) ed è portatile al 100% tra tutti i principali JRE.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.