A resposta tradicional do UNIX seria aquela que foi aceita para esta pergunta:
find . -name '*.java' | xargs grep -l 'string'
Isso provavelmente funcionará para arquivos Java, mas espaços em nomes de arquivos são muito mais comuns no Mac do que no mundo tradicional do UNIX. Quando nomes de arquivos com espaços são passados pelo pipeline acima, os xargs interpretarão as palavras individuais como nomes diferentes.
O que você realmente quer é separar os nomes para tornar os limites não ambíguos:
find . -name '*.java' -print0 | xargs -0 grep -l 'string'
A alternativa é deixar o find grep rodar para você, como Mark sugere, embora essa abordagem seja mais lenta se você estiver pesquisando um grande número de arquivos (como grep é invocado uma vez por arquivo ao invés de uma vez com toda a lista de arquivos).