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 ++?
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:
Java viene compilato una volta eseguito ovunque. C ++ viene scritto una volta compilato ovunque.
"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 JNI
che 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à.
Non è solo la lingua, sono le biblioteche.
Sia Java che C ++ forniscono librerie multipiattaforma. Java fornisce un set più ricco.
La differenza è che Java verrà eseguito su qualsiasi piattaforma senza ricompilazione. Avere un compilatore C ++ per ogni piattaforma non è affatto lo stesso.
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.
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.
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.
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 float
richiederebbe un'istruzione aggiuntiva rispetto al semplice caricamento direttamente a un registro di precisione esteso).
(int)
per la (x+1)
sottoespressione del primo esempio nel primo esempio, al parametro float
del secondo esempio x
, ma ovviamente non ho progettato il linguaggio .
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.
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.
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.
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.