В Java вы можете определить несколько классов верхнего уровня в одном файле, если только один из них является общедоступным (см. JLS §7.6 ). Смотрите ниже, например.
Есть аккуратное название этой техники (аналогично
inner
,nested
,anonymous
)?JLS говорит, что система может применять ограничение, которое эти вторичные классы не могут иметь
referred to by code in other compilation units of the package
, например, они не могут рассматриваться как закрытые для пакета. Это действительно что-то, что меняется между реализациями Java?
например, PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Ответы:
Мое предлагаемое имя для этого метода (включая несколько классов верхнего уровня в одном исходном файле) будет «беспорядок». Серьезно, я не думаю, что это хорошая идея - вместо этого я бы использовал вложенный тип в этой ситуации. Тогда все еще легко предсказать, в каком исходном файле он находится. Хотя я не верю, что для этого подхода есть официальный термин.
Что касается того, меняется ли это на самом деле между реализациями - я сильно сомневаюсь в этом, но если вы избегаете делать это в первую очередь, вам никогда не придется заботиться :)
источник
public int[] foo(int x)[] { return new int[5][5]; }
, даже если это действительно так.)javac не запрещает это активно, но у него есть ограничение, которое в значительной степени означает, что вы никогда не захотите ссылаться на класс верхнего уровня из другого файла, если он не имеет того же имени, что и файл, в котором он находится.
Предположим, у вас есть два файла, Foo.java и Bar.java.
Foo.java содержит:
Bar.java содержит:
Скажем также, что все классы находятся в одном пакете (и файлы находятся в одном каталоге).
Что произойдет, если Foo.java ссылается на Baz, а не на Bar, и мы пытаемся скомпилировать Foo.java? Компиляция заканчивается с ошибкой как это:
Это имеет смысл, если вы думаете об этом. Если Foo.java ссылается на Baz, но нет Baz.java (или Baz.class), как javac может знать, какой исходный файл искать?
Если вы вместо этого скажете javac скомпилировать Foo.java и Bar.java одновременно или даже если вы ранее скомпилировали Bar.java (оставив Baz.class, где javac может его найти), то эта ошибка исчезнет. Это делает ваш процесс сборки очень ненадежным и ненадежным.
Потому что действительное ограничение, которое больше похоже на «не ссылается на класс верхнего уровня из другого файла, если только у него нет того же имени, что и у файла, в котором он находится, или вы также ссылаетесь на класс, который находится в том же файле с именем то же самое, что и с файлом, довольно трудно понять, люди обычно придерживаются гораздо более простого (хотя и более строгого) соглашения, заключающегося в том, чтобы просто поместить один класс верхнего уровня в каждый файл. Это также лучше, если вы когда-нибудь передумаете, должен ли класс быть публичным или нет.
Иногда действительно есть веская причина, почему все делают что-то определенным образом.
источник
Я считаю , что вы просто вызываете ,
PrivateImpl
что это:non-public top-level class
. Вы также можете объявитьnon-public top-level interfaces
.например, в других местах SO: непубличный класс верхнего уровня против статического вложенного класса
Что касается изменений в поведении между версиями, было обсуждение о том, что «отлично работало» в 1.2.2. но перестала работать в 1.4 на форуме Sun. Java Compiler - не удалось объявить непубличные классы верхнего уровня в файле .
источник
non-public top level class
быть единственный класс в файле, поэтому он не учитывает множественность.secondary top level types
.Вы можете иметь столько классов, сколько пожелаете
источник
Мультиклассовая демонстрация одного файла.
Я не знаю ни одного, у кого нет этого ограничения - все файловые компиляторы не позволят вам ссылаться на классы исходного кода в файлах, которые не имеют имен, совпадающих с именем класса. (если вы скомпилируете файл с несколькими классами и поместите классы в путь к классам, тогда любой компилятор найдет их)
источник
Согласно изданию Effective Java 2 (пункт 13):
Вложенный класс может быть статическим или нестатическим в зависимости от того, нужен ли классу-члену доступ к включающему экземпляру (элемент 22).
источник
Да, вы можете, с открытыми статическими членами внешнего открытого класса, вот так:
и другой файл, который ссылается на выше:
положить их в одну папку. Компилировать с:
и запустить с:
источник
Просто к сведению, если вы используете Java 11+, есть исключение из этого правила: если вы запускаете свой Java-файл напрямую ( без компиляции ). В этом режиме нет ограничений на один публичный класс на файл. Однако класс с
main
методом должен быть первым в файле.источник
Нет, ты не можешь Но это очень возможно в Scala:
источник