Quando tive minha “primeira vez” com o Java, vinha de muito C/C++, de forma que entendo sua dúvida.
Devo confessar que demorei a me habituar a poder alocar objetos a torto e a direito sem ter que me preocupar com violações de acesso e vazamentos de memória. Acho que parte desta “neura” persiste até hoje, pois meu reflexo
instintivo me leva a tentar evitar o uso do “new” quando possível…
Anyway, como vc. está iniciando no Java com background de C/C++, acho que a melhor forma de entender o que acontece é imaginar que, na verdade, todos as variáveis cujo tipo descende da classe Object são ponteiros. Ou seja, em C/C++ vc. pode ter uma variável automática (aka stack-based) de um tipo complexo, que será desalocada no retorno da função. Em java, isto não existe. Tirando os tipos primitivos (char, int, byte, float, double, boolean - equeci algum ?), todos os outros são alocados no heap.
Isto significa que algumas contruções comuns em C/C++ não
terão o efeito esperado em Java. P.ex., atribuições do tipo a=b, onde “a” e “b” são variáveis não primitivas correspondem à uma cópia de ponteiros, ou seja, “a” aponta para a mesma área do heap apontada por “b”.