Я видел два способа сделать это.
Первый состоит в разделении публичного API и внутренних классов на два разных артефакта (jar).Документация также разделена, и, таким образом, конечному пользователю легко сделать различие между тем, что является внутренним, а что нет.Но иногда бывает сложнее иметь два jar, два исходных дерева и т. Д.
Второй состоит в том, чтобы доставить один jar, но имеет хорошую документацию, позволяющую узнать, что является внутренним, а что нет.Текстовая документация может объяснить, как использовать API (и, следовательно, избегать разговоров о внутренностях).А в javadoc можно указать, что класс предназначен для внутреннего использования и поэтому может быть изменен.