Domanda

Come dice la domanda, quali sono alcuni problemi comuni/principali che i programmatori C++ devono affrontare quando passano a Java?Sto cercando alcuni nomi o esempi di argomenti generali e gli aggiustamenti quotidiani che gli ingegneri hanno dovuto apportare.Poi posso andare a fare una lettura approfondita su questo.

Sono particolarmente interessato alle opinioni di ingegneri che hanno lavorato in C++ per anni e hanno dovuto lavorare con Java, ma qualsiasi suggerimento da parte di altri o anche consigli sui libri sono più che benvenuti.

È stato utile?

Soluzione

  • In C++ utilizzeresti i distruttori per ripulire i descrittori di file, le connessioni al database e simili.L'equivalente ingenuo è usare i finalizzatori.Non.Mai.

Utilizza invece questo modello:

OutputStream os;
try {
  os = ... 
  // do stuff
} finally {
  try { os.close(); } catch (Exception e) { }
}

Finirai per fare spesso cose del genere.

  • Se non specifichi alcun modificatore di accesso, in Java i membri sono privati ​​del pacchetto per impostazione predefinita, a differenza del C++ in cui sono privati.Package-private è un livello di accesso fastidioso, il che significa che è privato ma anche qualsiasi cosa nello stesso pacchetto può accedervi (che è un livello di accesso predefinito idiota, secondo me);
  • Non esiste separazione stack/heap.Tutto viene creato sull'heap (beh, non è del tutto vero ma faremo finta che lo sia);
  • Non esiste alcun riferimento pass-by;
  • L'equivalente dei puntatori a funzione sono le interfacce anonime.

Altri suggerimenti

Il mio più grande ostacolo da C ++ a Java è stato quello di abbandonare il codice procedurale. Ero molto abituato a legare tutti i miei oggetti all'interno delle procedure. Senza codice procedurale in Java, ho fatto riferimenti circolari ovunque. Ho dovuto imparare a chiamare oggetti da oggetti senza che fossero dipendenti l'uno dall'altro. Era l'ostacolo più grande ma il più facile da superare.

Il problema personale numero 2 è la documentazione. JavaDoc è utile, ma per molti progetti java sono nell'idea sbagliata che tutto ciò che serve è JavaDoc. Ho visto una documentazione molto migliore nei progetti C ++. Questa potrebbe essere solo una preferenza personale per la documentazione al di fuori del codice.

Numero 3. Esistono in realtà puntatori in java, ma nessun aritmetica dei puntatori . In java sono chiamati riferimenti . Non pensare che puoi ignorare dove puntano le cose, tornerà con un grande morso.

  • == e .equals non sono uguali.

  • == guarderà il puntatore (riferimento) mentre .equals guarderà il valore a cui punta il riferimento.

Generics (anziché i modelli), in particolare il modo in cui sono stati implementati utilizzando cancellazione di tipo .

Dato che menzioni consigli sui libri, leggi sicuramente Java efficace, 2a ed.—affronta la maggior parte delle insidie ​​​​che ho visto elencate nelle risposte.

Creazione accidentale di un riferimento quando si pensava a un costruttore di copie:

myClass me = new myClass();
myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */
somebodyElse.setPhoneNumber(5551234);
/* Hey... how come my phone doesn't work anymore?!?!?  */
  • Nessuna eredità multipla, e ogni classe deriva implicitamente da java.lang.Object (che ha una serie di metodi importanti che devi assolutamente conoscere e comprendere)
  • Puoi avere una sorta di eredità multipla implementando interfacce
  • Nessun sovraccarico da parte dell'operatore tranne '+' (per le stringhe) e sicuramente nessuno che puoi fare da solo
  • Nessun tipo numerico senza segno, tranne char, che non dovrebbe essere usato come tipo numerico. Se hai a che fare con tipi non firmati, devi fare molto casting e mascheramento.
  • Le stringhe non hanno una terminazione nulla, ma si basano su array di caratteri e come tali sono immutabili. Di conseguenza, costruire una stringa lunga aggiungendo + = in un ciclo è O (n ^ 2), quindi non farlo; usa invece StringBuilder.

Abituarsi ad avere un garbage collector. Non essere in grado di fare affidamento su un distruttore per ripulire le risorse che il GC non gestisce.

Tutto viene passato per valore, perché i riferimenti vengono passati invece degli oggetti.

Nessun costruttore di copie, a meno che non sia necessario clonare. Nessun operatore di assegnazione.

Tutti i metodi sono virtuali per impostazione predefinita, che è l'opposto di C ++.

Supporto esplicito del linguaggio per le interfacce - classi virtuali pure in C ++.

Sono tutte le piccole differenze di sintassi che mi hanno procurato. Mancanza di distruttori.

D'altra parte, essere in grado di scrivere un main per ogni classe (immensamente utile o test) è davvero bello; dopo esserti abituato, la struttura e i trucchi disponibili con i file jar sono davvero belli; il fatto che la semantica sia completamente definita (ad esempio, int è la stessa ovunque) è davvero bello.

Il mio peggior problema era tenere sempre presente la proprietà della memoria. In C ++, è una cosa necessaria da fare e crea alcuni schemi nella mente dello sviluppatore che sono difficili da superare. In Java, posso dimenticarmene (in larga misura, comunque), e questo abilita alcuni algoritmi e approcci che sarebbero estremamente imbarazzanti in C ++.

Non ci sono oggetti in Java, ci sono solo riferimenti ad oggetti. Ad esempio:

MyClass myClass;   // no object is created unlike C++.

Ma:

MyClass myClass = new MyClass();   // Now it is a valid java object reference.

Il miglior libro di "trucchi" Java che ho letto è Puzzle Java:Trappole, insidie ​​e casi d'angolo.Suo non rivolto specificamente agli sviluppatori C++, ma è pieno di esempi di cose a cui vuoi prestare attenzione.

Specificare un parametro del metodo come final non significa che cosa pensi all'inizio significhi

private void doSomething(final MyObject myObj){
   ...
   myObj.setSomething("this will change the obj in the calling method too");
   ...
}

poiché java è pass per valore, sta facendo quello che stai chiedendo, ma non immediatamente ovvio a meno che tu non capisca come java passa il valore del riferimento piuttosto che l'oggetto.

Un altro notevole è la parola chiave final e const. Java definisce const come una parola chiave riservata ma non specifica gran parte del suo utilizzo. Inoltre

object1=object2

non copia gli oggetti, cambia il riferimento

Tutti i metodi sono virtuali.

I tipi con parametri (generici) in realtà non creano codice specifico per parametro del codice (ovvero, List<String> utilizza lo stesso bytecode di List<Object>; il compilatore è l'unica cosa che si lamenta se si tenta di inserire un Integer in il primo).

Varargs è facile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top