Java: Несколько объявлений класса в одном файле

В Java можно определить несколько высокоуровневых классов в единственном файле, если это самое большее один из них общедоступен (см. JLS §7.6). Посмотрите ниже, например.

  1. Есть ли опрятное название этой техники (аналогичный inner, nested, anonymous)?

  2. 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;
}

230
задан Victor Dombrovsky 3 August 2015 в 00:56
поделиться

4 ответа

Мое предложенное имя для этого метода (включая несколько классов верхнего уровня в одном исходном файле) было бы "беспорядок". Серьезно, я не думаю, что это хорошая идея - вместо этого я бы использовал вложенный тип в этой ситуации. Тогда все еще легко предсказать, в каком исходном файле он находится. Я не верю, что есть официальный термин для этого подхода.

Что касается того, действительно ли это меняется между реализациями - я очень сомневаюсь в этом, но если вы в первую очередь избегаете этого, вам никогда не придется беспокоиться :)

119
ответ дан 23 November 2019 в 03:41
поделиться

1. Есть ли у этой техники аккуратное название (аналогичное внутреннему, вложенному, анонимному)?

Мультиклассовая однофайловая демонстрация.

2. В JLS говорится, что система может применять ограничение, согласно которому на эти вторичные классы нельзя ссылаться с помощью кода в других единицах компиляции пакета, например, они не могут рассматриваться как частные для пакета. Это действительно что-то, что меняется между реализациями Java?

Я не знаю ни одной, которая не имеет этого ограничения - все компиляторы на основе файлов не позволят вам ссылаться на классы исходного кода в файлах, которые не имеют имени то же, что и название класса. (если вы скомпилируете файл с несколькими классами и поместите классы в путь к классам, то любой компилятор найдет их)

4
ответ дан 23 November 2019 в 03:41
поделиться

javac активно не запрещает это, но у него есть ограничение, которое в значительной степени означает, что вы никогда не захотите ссылаться на класс верхнего уровня из другого файла, если его имя не совпадает с именем файла, в котором он находится.

Предположим, у вас есть два файла, Foo.java и Bar.java.

Foo.java содержит:

  • открытый класс Foo

Bar.java содержит:

  • открытый класс Bar
  • класс Baz

Предположим также, что все классы находятся в одном пакете ( и файлы находятся в одном каталоге).

Что произойдет, если 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 может его найти), тогда эта ошибка исчезнет. Однако из-за этого процесс сборки выглядит очень ненадежным и нестабильным.

Поскольку фактическое ограничение, которое больше похоже на «не относитесь к классу верхнего уровня из другого файла, если он не имеет того же имени, что и файл, в котором он находится, или вы также ссылаетесь на класс, который находится в том же самом файле». "файл, названный так же, как и файл", трудно понять, люди обычно придерживаются гораздо более простого (хотя и более строгого) соглашения, заключающегося в том, что просто помещают один класс верхнего уровня в каждый файл. Это также будет лучше, если вы когда-нибудь передумаете, должен ли класс быть публичным или нет.

Иногда действительно есть веская причина, почему каждый делает что-то определенным образом.

124
ответ дан 23 November 2019 в 03:41
поделиться

Я полагаю, вы просто вызываете PrivateImpl , что это такое: закрытый класс верхнего уровня . Вы также можете объявить непубличные интерфейсы верхнего уровня .

например, в другом месте на SO: Непубличный класс верхнего уровня против статического вложенного класса

Что касается изменений в поведении между версиями, было обсуждение того, что «отлично работает» в 1.2 .2. но перестал работать в 1.4 на форуме Sun: Компилятор Java - невозможно объявить закрытые классы верхнего уровня в файле .

22
ответ дан 23 November 2019 в 03:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: