Perché Java non consente l'uso delle intestazioni come in C ++


18

Ho una domanda per la quale non ho trovato una risposta tranne la seguente risposta che non soddisfa i miei requisiti:

"Perché James Gosling non voleva"

So che Java può avere interfacce (solo funzioni virtuali pure, nessun attributo), ma non è esattamente la stessa cosa delle definizioni di classe.


14
Qual è il motivo per cui li vuoi?

19
Avere più tempo per gli
scontri con la

6
Suppongo che la maggior parte degli sviluppatori C ++ adorerebbe sbarazzarsi del motore di sostituzione del testo di 40 anni che duplica centinaia di kLoC per ogni file cpp, portando a lunghi tempi di compilazione di C ++. In effetti, per C ++ 11 è stato previsto un sistema di moduli adeguato, ma è stato abbandonato a causa della mancanza di tempo. Suppongo che tornerà, però.
sbi,

Suppongo che tornerà, però. In effetti, WG21 (il gruppo di lavoro ISO C ++) ha un gruppo di studio al solo scopo di valutare / sviluppare ulteriormente il concetto di "moduli": SG2 "Moduli". Peccato che lo stato attuale sia inattivo .
Max Truxa,

Risposte:


46

La seguente risposta che non soddisfa i miei requisiti: "Perché James Gosling non voleva."

Questa è la risposta giusta, però. Il team di progettazione linguistica (Gosling, Sheridan, Naughton, in seguito Bill Joy, Ken Arnold, ecc.) Ha deciso che le intestazioni causavano più problemi di quanti ne risolvessero . Così le hanno progettate e hanno dimostrato che potevano creare un linguaggio perfettamente utile senza che fosse necessario.

Dalla sezione 2.2.1 del white paper Java Language Environment :

Il codice sorgente scritto in Java è semplice. Non vi è alcun preprocessore, nessuna #define e funzionalità correlate, nessun typedef e assente tali funzionalità, non è più necessario alcun file di intestazione. Invece dei file header, i file sorgente in linguaggio Java forniscono le definizioni di altre classi e i loro metodi.

Definizioni ridondanti, sincronizzazione dei file, definizioni in conflitto, definizioni nascoste: nessuna di queste si verifica in Java, perché non si hanno intestazioni. Se vuoi vedere una definizione di classe nuda, puoi generarne una direttamente da un file .java, ad esempio la maggior parte degli IDE ti mostrerà la struttura di una classe in una barra laterale, che equivale alla stessa cosa.


6
Grazie per la risposta, quindi, le intestazioni hanno causato più problemi a causa di ciò: definizioni ridondanti, sincronizzazione dei file, definizioni contrastanti, definizioni nascoste. È per questo che non è stato permesso?
Etienne Noël,

2
Si noti che si parla molto delle prossime riunioni del Comitato C ++ perché considereranno un nuovo sistema "Modulo" che sarebbe un sistema più semplice ed efficiente rispetto a includere (con alcune somiglianze con i pacchetti Java, C # ecc.) Ma ancora retrò -compatibile con include. Ciò significa che un sistema di compilazione migliore può, almeno in teoria, essere utilizzato per rendere la compilazione C ++ migliore / più efficiente. Gosling aveva ragione immagino, e C ++ deve comunque trovare un modo per risolvere il sistema di inclusione.
Klaim,

5
Non è perfettamente utilizzabile. I sistemi di generazione Java non sono in grado di determinare quali file devono essere ricompilati dopo una modifica del codice. Un IDE determinerà quali file richiedono una modifica del codice, ma non quali devono essere ricompilati. Se la firma di un metodo cambia, ma la modifica è compatibile con il codice con la vecchia firma (ad es. Modifica di un tipo di argomento da float a double), è necessaria una build pulita per impedire MethodNotFoundException.
Kevin Cline,

1
@kevin: Tuttavia, di solito è possibile ricostruire tutto senza costi eccessivi. A differenza del C ++ (ma come quasi tutti gli altri linguaggi compilati sulla terra) Java non impiega molto tempo a compilare che la compilazione parziale è un'ottimizzazione molto utile del flusso di lavoro di sviluppo.
Donal Fellows

1
@Donal: È vero che Java si compila abbastanza rapidamente, ma odio indovinare se dovrei fare una ricompilazione completa. Le build dovrebbero funzionare, ogni volta.
Kevin Cline il

16

In C ++ non è necessario disporre delle definizioni e delle dichiarazioni di classe in file separati. Significa solo che potresti, almeno nei giorni C, eseguire l'analisi in una singola scansione dall'alto in basso del codice. Su macchine senza memoria ad accesso casuale questo è stato un grosso problema!

Avere le intestazioni ti ha anche permesso di pubblicare l'interfaccia nella tua libreria di codici fornendo l'intestazione senza dover rivelare il codice sorgente. Sfortunatamente in C ++ devi anche rivelare i membri di dati privati ​​che hanno portato a soluzioni come l'orrore di pimpl .

Ci sono stati tentativi di creare un ambiente C ++ in cui tutto è stato archiviato in una struttura di tipo di database e non ci sono file ma non ha funzionato.


Lo so, ma almeno puoi farlo in C ++ non in Java; quella era la mia richiesta principale. Grazie per la risposta.
Etienne Noël,

14

A causa del principio DRY . In Java, le informazioni necessarie per utilizzare le classi in un pacchetto (o classe) sono contenute all'interno del file .class. La creazione di file di intestazione separati che contengono le stesse informazioni comporterebbe la ripetizione in due punti.


sfortunatamente, spesso vuoi ripeterlo: pensa ai file wsdl, ai file idl ecc. Uno descrive l'interfaccia che puoi usare e un altro file contiene l'implementazione. Le intestazioni C ++ sono definizioni di interfaccia (scadenti).
gbjbaanb,

6

In ogni lingua - ci sono due fasi per la creazione del codice binario finale - la compilazione e il collegamento (ovviamente, si sta caricando ma non ha molto impatto qui). Al momento della compilazione è sufficiente posizionare gli hook (la specifica delle funzioni che verranno chiamate) nel posto appropriato. Linker si unisce effettivamente a loro quando sono disponibili entrambi i codici reali. Finora non c'è differenza tra C ++ e Java.

V'è , tuttavia, la necessità di C ++ per avere dichiarazione e definizione distinta. Se si mantiene l'implementazione nell'intestazione e se il file di intestazione cambia, è necessario ricompilare il codice ad esso collegato. Dove come se la definizione fosse in un file separato, il codice deve solo essere ricollegato.

Comprendere che C ++ ha un'opzione per avere un collegamento statico che implica che il codice oggetto sia corretto insieme all'applicazione chiamante. Si noti che sia in C che in C ++, non è valido avere la programmazione nel file di intestazione o addirittura fare #include. significa solo che devi preoccuparti di come avviene il collegamento con questi file oggetto.

La situazione in Java è molto diversa. Ogni file di classe viene compilato con il file .class. In effetti, la necessità di compilare la funzione della classe del chiamante che viene servita come sezione di intestazione nel file .class. Tuttavia, in Java il collegamento finale viene eseguito solo all'interno del Runtime (la macchina virtuale) solo con quella specifica specifica del codice byte del file di classe.

Vedi questo e questo


4

In effetti le interfacce e include sono le intestazioni; le definizioni sono quindi identiche ai binari e non possono essere fuori sincrono. Questa è una delle migliori decisioni di progettazione in Java, ma è un piccolo fastidio che non ci sia modo di raggruppare queste dichiarazioni per compattezza e coerenza.


1

Un buon motivo per includere le inclusioni è separare il codice che potresti voler riutilizzare (come definizioni comuni) dal codice specifico per un determinato progetto. Java vuole che tu specifichi solo una classe o un'interfaccia per file e ciò riduce principalmente la necessità di intestazioni incluse, poiché per te le parti condivise saranno già nei loro file.

Inoltre, compilatori e sistemi di compilazione potrebbero voler memorizzare nella cache intestazioni precompilate per evitare di analizzarle più di una volta.


1
Suppongo che potresti archiviare le interfacce in un progetto condiviso e quindi implementarle in progetti indipendenti
Alexander Mills
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.