Em todos os idiomas - há dois estágios para a criação do código binário final - compilação e vinculação (é claro, há carregamento, mas isso não tem muito impacto aqui). No momento da compilação, é necessário colocar os ganchos (a especificação das funções que serão chamadas) no local apropriado. O Linker realmente os une quando o código real está disponível. Até o momento, não há diferença entre C ++ e Java.
Não é , no entanto, a necessidade de C ++ para ter declaração e definição separada. Se você mantiver a implementação no cabeçalho e se o arquivo do cabeçalho for alterado, o código vinculado a ele precisará ser recompilado. Onde como se a definição estivesse em um arquivo separado, o código só precisa ser vinculado novamente.
Entenda que o C ++ tem a opção de ter vínculo estático, o que implica que o código do objeto seja corrigido junto com o aplicativo de chamada. Observe que, tanto em C como em C ++, não é inválido ter programação no arquivo de cabeçalho ou até mesmo #include. isso significa apenas que você precisa se preocupar sobre como a vinculação acontece com esses arquivos de objeto.
A situação em Java é muito diferente. Cada arquivo de classe é compilado com o arquivo .class. De fato, a necessidade de compilação de funções de classe de chamador, que é servida como uma seção de cabeçalho no arquivo .class. No entanto, no Java, a vinculação final é feita apenas dentro do Runtime (a máquina virtual) apenas com essa especificação do código de bytes do arquivo de classe.
Veja isso e isso