javac активно не запрещает это, но у него есть ограничение, которое в значительной степени означает, что вы никогда не захотите ссылаться на класс верхнего уровня из другого файла, если у него нет того же имени, что и у файла, в котором он находится.
Предположим, у вас есть два файла: Foo.java и Bar.java.
Foo.java содержит:
Bar.java содержит:
- Бар общественного класса
- класс Баз
Скажем также, что все классы находятся в одном пакете (и файлы находятся в одном каталоге).
Что произойдет, если Foo.java ссылается на Baz, но не Bar, и мы пытаемся скомпилировать Foo.java? Компиляция завершается с ошибкой, подобной этой:
Foo.java:2: cannot find symbol
symbol : class Baz
location: class Foo
private Baz baz;
^
1 error
Это имеет смысл, если вы думаете об этом. Если Foo.java ссылается на Baz, но нет Baz.java (или Baz.class), как javac может знать, какой исходный файл искать?
Если вместо этого вы скажете javac скомпилировать Foo.java и Bar.java одновременно или даже если вы ранее скомпилировали Bar.java (оставив Baz.class, где javac может его найти), то эта ошибка исчезнет. Однако это делает процесс сборки очень ненадежным и ненадежным.
Потому что действительное ограничение, которое больше похоже на «не ссылается на класс верхнего уровня из другого файла, если только у него нет того же имени, что и у файла, в котором он находится, или вы также ссылаетесь на класс, который находится в том же самом» «Файл, который называется так же, как и файл», довольно сложен для понимания, люди обычно придерживаются гораздо более простого (хотя и более строгого) соглашения, заключающегося в том, чтобы просто поместить один класс верхнего уровня в каждый файл. Это также лучше, если вы когда-нибудь передумаете, должен ли класс быть публичным или нет.
Иногда действительно есть веская причина, почему все делают что-то определенным образом.