Stai confondendo l'immutabilità del riferimento all'oggetto e l'immutabilità dell'oggetto stesso. Sono cose separate.
laptop.memory è solo un riferimento (puntatore) all'oggetto. Questo può essere modificato, cioè puoi cambiare il riferimento per puntare a un oggetto diverso - che è esattamente quello che hai fatto - hai creato un secondo oggetto String contenente "2GB" e assegnato il suo riferimento (puntatore) a laptop.memory. L'oggetto String originale non è ancora modificato (o forse è garbage collection).
Lo stesso comportamento si applica a tutti gli oggetti in Java, ma le primitive sono diverse (non hanno riferimenti e sono realmente modificate direttamente).
BTW, puoi avere un riferimento immutabile in Java con la parola chiave finale:
class Laptop {
final String memory = "1GB";
}
Con questa modifica, il tuo codice non verrà compilato perché tenti di modificare il riferimento.