Toda String em java é imutável ela nasce com um tamanho e morre com ele isso é fato
o que acontece que quando você faz qualquer operação entre Strings, não importa qual seja (subString, StringA + StringB, conctenação, append) o que for o que o java faz é criar uma nova String em cima da String antiga
exemplo :
String a = "ola";
String b = "Mundo";
a = a + b;
nesse exemplo de cima a String “ola” original morre ela vai deixar de existir, e no lugar dela vira a String “olaMundo” substituindo o seu lugar
tenha muito cuidado ao fazer operações com String em java isso pode deixar a sua aplicação muito lento, eu lembro que uma vez fiz um programa que demorava 10 min para rodar o motivo dessa demora era por causa das inúmeras concatenações que minha String fazia.
Já ao usar o StringBuilder ele é uma String que o tamanho pode variar, assim concatenar Strings com ele não é um processo pesado, para você ter ideia essa minha aplicação que levava 10 min para rodar ao usar StringBuilder ela passou a levar 30 segundos
so usando o seu exemplo :
String x = "Andre L";
x = x.replaceAll("L","?");
quando você faz “x.replaceAll(“L”,”?");" você está gerando uma nova String diferente da original também e substituindo