Sono molto simili; entrambi fanno riferimento alle istanze degli oggetti in memoria, ma il modo in cui la lingua consente di manipolarli è diverso.
In Java, un riferimento punta a un'istanza di oggetto in memoria. È possibile riassegnare questo riferimento in modo che punti in un'altra istanza nella memoria in qualsiasi momento:
SomeObject ref = new SomeObject();
ref.doSomeWork();
...
ref = new SomeObject();
In C ++, un riferimento non può essere riassegnato per puntare a un oggetto diverso - punta sempre alla stessa posizione di memoria.
I puntatori in C ++ sono più simili ai riferimenti Java rispetto ai riferimenti C ++ - puoi cambiare l'oggetto a cui puntano. Sono anche un po 'più flessibili dei riferimenti Java, perché puoi manipolare il puntatore stesso, come incrementarlo per puntare a un altro oggetto in un elenco:
SomeObject* ptr = {instance1, instance2, instance3};
ptr->doSomeWork(); // calls instance1's doSomeWork method
ptr++;
ptr->doSomeWork(); // calls instance2's doSomeWork method
Come sottolineato da @DennisBraga (pun), con i puntatori si ottiene l'accesso all'indirizzo di memoria dell'oggetto, ma con i riferimenti (in Java) non lo si fa. Inoltre, con i puntatori devi dereferenziare in qualche modo per raggiungere l'oggetto, ma con i riferimenti Java questo accade dietro le quinte per te.