Почему каждый общедоступный класс в отдельном файле?

Существует два использования для ключевого слова, статичного когда дело доходит до функций в C++.

первое должно отметить функцию как наличие внутренней связи, таким образом, на это нельзя сослаться в других единицах перевода. Это использование удерживается от использования в C++. Пространства имен без имени предпочтены для этого использования.

// inside some .cpp file:

static void foo();    // old "C" way of having internal linkage

// C++ way:
namespace
{
   void this_function_has_internal_linkage()
   {
      // ...
   }
}

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

45
задан Peter Mortensen 20 October 2009 в 07:22
поделиться

11 ответов

Согласно Спецификации языка Java, Третье издание :

Это ограничение подразумевает, что на единицу компиляции должно быть не более одного такого типа. Это ограничение упрощает компилятору языка программирования Java или реализации виртуальной машины Java поиск именованного класса в пакете ; например, исходный код для открытого типа wet.sprocket.Toad можно найти в файле Toad.java в каталоге wet / sprocket, а соответствующий объектный код - в файле Toad.class в том же каталоге.

Особое внимание уделяется мне.

Похоже, что в основном они хотели перевести разделитель каталогов ОС в точки для пространств имен, и наоборот.

Так что да, это было неким дизайнерским соображением.

33
ответ дан 26 November 2019 в 20:56
поделиться

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

Если у вас есть несколько общедоступных классов в файле, у вас есть несколько проблем:

  1. Как вы назовете файл? Один из публичных классов? Другое имя? У людей достаточно проблем, связанных с плохой организацией кода решения и соглашениями об именах файлов, чтобы иметь одну дополнительную проблему.

  2. Кроме того, когда вы просматриваете проводник файлов / проектов, хорошо, что все не скрыто. Например, вы видите один файл и просматриваете детали, и все 200 классов собраны вместе. Если у вас есть один файл и один класс, вы сможете лучше организовать свои тесты и почувствовать структуру и сложность решения.

Я думаю, что Java сделала это правильно.

57
ответ дан 26 November 2019 в 20:56
поделиться

Из Мышление на Java

:

На единицу компиляции (файл) может быть только один публичный класс.
Идея состоит в том, что каждая единица компиляции имеет единственный открытый интерфейс, представленный этим открытым классом . У него может быть столько поддерживающих «дружественных» классов, сколько вы захотите. Если у вас есть более одного общедоступного класса внутри модуля компиляции, компилятор выдаст вам сообщение об ошибке.


Из спецификации (7.2.6)

Когда пакеты хранятся в файловой системе (? 7.2 .1), хост-система может выбрать для обеспечения ограничения, что это ошибка времени компиляции, если тип не найден в файле под именем, состоящим из имени типа плюс расширение (например, .java или .jav), если выполняется одно из следующих условий :

  • На тип ссылается код в других единицах компиляции пакета, в котором тип объявлен.
  • Тип объявлен общедоступным (и поэтому потенциально доступен из кода в других пакетах).
  • Это ограничение подразумевает, что на единицу компиляции должно быть не более одного такого типа.
  • Это ограничение упрощает компилятору языка программирования Java или реализации виртуальной машины Java поиск именованного класса в пакете ; например, исходный код для открытого типа wet.sprocket.Toad можно найти в файле Toad.java в каталоге wet / sprocket, а соответствующий объектный код - в файле Toad.class в том же каталоге.

Вкратце: это может быть о поиске классов без необходимости загружать все на свой путь к классам.

Изменить: "может выбрать" кажется, что оставляет возможность не следовать этому ограничению, Однако на практике это применяется на очень многих платформах и зависит от такого количества инструментов и IDE, что я не вижу, чтобы какая-либо «хост-система» решила , а не применять это ограничение.


From " ] Once Upon an Oak ... "

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

(Примечание:

Спецификация языка Oak для Oak версии 0.2 (постскрипт): Oak было оригинальным названием того, что сейчас широко известно как Java, и это руководство является самым старым из доступных для Oak (то есть Java).
Чтобы узнать больше об истоках Java, ознакомьтесь с Green Project и Java ™ Technology: An Early History
)

17
ответ дан 26 November 2019 в 20:56
поделиться

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

Вы должны помнить, что язык Java был разработан в середине 90-х, , за дни до того, как IDE сделали навигацию по коду и поиск с легкостью .

6
ответ дан 26 November 2019 в 20:56
поделиться

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

Если класс используется несколькими другими классами, какой из этих классов вы бы поместили в тот же файл? Все трое? В итоге все ваши классы будут в одном файле ...

3
ответ дан 26 November 2019 в 20:56
поделиться

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

3
ответ дан 26 November 2019 в 20:56
поделиться

Почему Java не снимает это ограничение сейчас, в эпоху IDE? Это не повредит существующий код (или не повредит?).

Теперь весь код единообразен. Когда вы видите исходный файл, вы знаете, чего ожидать. это одинаково для каждого проекта. Если java удалит это соглашение, вам придется заново изучать структуру кода для каждого проекта, над которым вы работаете, где, как сейчас, вы изучаете ее один раз и применяете везде. Мы не должны во всем доверять IDE.

2
ответ дан 26 November 2019 в 20:56
поделиться

Технически допустимо иметь несколько классов верхнего уровня Java в одном файле. Однако это считается плохой практикой, и многие инструменты Java (включая IDE) не работают, если вы это сделаете.

JLS говорит следующее:

Когда пакеты хранятся в файле система (§7.2.1), хост-система может принять решение о применении ограничения , которое это ошибка времени компиляции, если тип не найден в файле под именем состоит из названия типа плюс расширение (например, .java или .jav), если верно одно из следующих утверждений:

  • На тип ссылается код в других единицах компиляции пакета, в котором этот тип объявлен.
  • Тип объявлен общедоступным (и поэтому потенциально доступен из кода в других пакетах.

Обратите внимание на использование may в тексте JLS. Это говорит о том, что компилятор может отклонить это как недопустимое, а может и нет. Это не очень хорошая ситуация, если вы пытаетесь создать свой Java-код, который будет переносимым на уровне исходного кода . Таким образом, даже если несколько классов в одном исходном файле работают на вашей платформе разработки, это плохая практика.

Насколько я понимаю, это «разрешение на отклонение» является дизайнерским решением, частично , чтобы упростить реализацию Java на более широком спектре платформ. Если (наоборот) JLS потребует, чтобы все компиляторы поддерживали исходные файлы, содержащие несколько классов, возникнут концептуальные проблемы с реализацией Java на платформе, не основанной на файловой системе.

На практике опытные разработчики Java вообще не упускают возможности сделать это. Модуляризация и сокрытие информации лучше выполнять с использованием соответствующей комбинации пакетов, модификаторов доступа к классам и внутренних или вложенных классов.

2
ответ дан 26 November 2019 в 20:56
поделиться

Not really an answer to the question but a data point none the less.

I grepped the headers of my personal C++ utilty library (you can get it yourself from here) and almost all of the header files that actually do declare classes (some just declare free functions) declare more than one class. I like to think of myself as a pretty good C++ designer (though the library is a bit of a bodge in places - I'm its only user), so I suggest that for C++ at least, multiple classes in the same file are normal and even good practice.

1
ответ дан 26 November 2019 в 20:56
поделиться

Он позволяет использовать более простые эвристические методы для перехода от Foobar.class к Foobar.java.

Если Foobar может быть в любом файле Java, у вас есть проблема с отображением, что в конечном итоге может означать, что вам нужно выполнить полное сканирование всех файлов Java, чтобы найти определение класса.

Лично я обнаружил, что это одно из странных правил, которые в совокупности приводят к тому, что приложения Java могут вырасти очень большими и при этом оставаться устойчивыми.

1
ответ дан 26 November 2019 в 20:56
поделиться

В одном классе может быть много открытых классов. один файл. Однако класс верхнего уровня для каждого файла. Для каждого файла может быть столько общедоступных внутренних / вложенных классов, сколько вам нужно.

Думаю, вам понравится эта ссылка - Может ли файл java иметь более одного класса ?

1
ответ дан 26 November 2019 в 20:56
поделиться
Другие вопросы по тегам:

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