Чому Java дозволяє нам складати клас з іменем, відмінним від імені файлу?


170

У мене є файл Test.javaі наступний код всередині нього.

public class Abcd
{
        //some code here

}

Тепер клас не компілюється, але коли я видаляю publicмодифікатор, він компілює чудово.

Які міркування Java дозволяють скласти ім’я класу, яке відрізняється від імені файлу, коли воно не є загальнодоступним.

Я знаю, що це питання для новачків, але я не в змозі знайти хорошого пояснення.


28
Тому що Java. (Оскільки це не публічно, і не потрібно дотримуватися тієї ж конвенції про іменування. Крім того, вам потрібно буде попросити людей, які його вигадали.)
Дейв Ньютон

2
Я сумніваюся, що є "гарне пояснення". Це було вимогою до публічних класів, але вважалося непотрібним для непублічних класів.
Каяман

2
Схоже , подібне питання: stackoverflow.com/questions/7633631 / ...
Санкет

4
Чому так багато пропозицій щодо цього питання, насамперед його дублюючого питання: stackoverflow.com/questions/7633631/…
GM Ramesh

2
@ Рамеш: назва та зміст цього питання краще .. (ніж інші подібні)
Jayan

Відповіді:


325

Обгрунтування полягає в тому, щоб дозволити більше одного класу верхнього рівня в одному .javaфайлі.

Багато класів - наприклад, слухачі подій - лише для місцевого використання, і найдавніші версії Java не підтримували вкладені класи. Без цього послаблення правила "ім'я файлу = ім'я класу", кожен такий клас потребував би свого власного файлу з неминучим результатом нескінченного розповсюдження невеликих .javaфайлів та розсіювання щільно зв'язаного коду.

Як тільки Java представила вкладені класи, важливість цього правила значно зменшилася. Сьогодні ви можете пройти багато сотень файлів Java, ніколи не переживаючи того, хто цим скористається.


60
+1, це фактично є причиною , в чому полягає питання.
Дейв Ньютон

4
+1, особливо для історичної інформації - я підозрюю, що з появою вкладених / анонімних класів, якби те саме рішення було прийнято зараз (не піклуючись про зворотню сумісність), було б набагато більше сенсу просто дозволити один клас вищого рівня на файл.
Майкл Беррі

1
@ berry120 Цілком певно, тому що ця надбавка ускладнює пошук файлів під час компіляції.
Марко Топольник

3
@ Val Заперечуючи, що інші люди вважають за краще використовувати текстовий редактор та інструменти CLI для розробки, тому що ви IDE, який ви віддаєте перевагу, існує так само нерозумно, як сказати, що немає сенсу створювати IDE, оскільки ви можете робити розробку без них. Обидва підходи використовуються хорошими розробниками для створення якісного коду; і єдине, що менше шансів у всіх розробників, які влаштують один із них і заспівають кумбаю, - це шанси, що всі ми погодимось, що таке найкраща мова програмування.
Ден піднімається Firelight

5
Поєднання Emacs (або Vim, виберіть свою отруту) та утиліти для оболонки Unix, мабуть, не настільки все, що під рукою, як сучасний IDE, і їм, звичайно, важче навчитися, але вони мають дві переважні переваги порівняно з кожен IDE, який я коли-небудь намагався: вони ніколи не виходять з ладу, незалежно від того, наскільки величезна база даних, і вони можуть бути в курсі мого набору тексту.
zwol

80

Причина така ж, як і для дверних плит. Якщо якась особа офіційно проживає в офісі (оголошена громадськістю), її прізвище повинно бути на дверях. На кшталт "Алекс Джонс" або "детектив Коломбо". Якщо хтось просто відвідує кімнату, розмовляє з чиновником або прибирає підлогу, їхнє ім’я не повинно офіційно ставитись у двері. Натомість у дверях можна прочитати "Утиліти" чи "Кімната для нарад".

Офіційне ім’я або MyClass.java Конференц-зал або Test.java


4
Однозначно цікава аналогія; це може бути ще краще, якщо трохи пояснити, як це стосується безпосередньо. У ОП можуть виникнути певні труднощі з підключенням (хоча я це прекрасно розумію)
Ендрю Барбер

4
@AndrewBarber Я не думаю, що аналогія насправді підходить, оскільки вона не моделює єдиний публічний клас, обмінюючи файл декількома класами пакет-приват. Це як на дверній табличці написано "Хізер Санті, менеджер", але кімната насправді містить Хізер та її двох секретарів.
Марко Топольник

@MarkoTopolnik я не мав би вступати в це; Я клас-A жахливий у аналогіях! ;)
Ендрю Барбер

@AndrewBarber я все-таки хотів це написати; Ви щойно підштовхнули :) Аналогія також не висловлює найгострішого занепокоєння: саме завдяки цій функції компілятор повинен проаналізувати всі файли, щоб виявити всі класи, інакше він міг би просто прочитати список каталогів і знати назви всіх класи вищого рівня.
Марко Топольник

@AndrewBarber, аналогія ідеально підходить до ідеї каталогів, у довгому коридорі ви можете швидко знайти людину, просто поглянувши на дверні таблички, вам не потрібно зайти в кожну кімнату і запитати.
exebook

29

У специфікації Java зазначено, що у вас може бути лише максимум один публічний клас на файл. У цьому випадку ім'я класу повинно відповідати імені файлу. Усі непублічні класи можуть мати будь-яке ім’я, незалежно від імені файлу.


20
Але "які міркування Java дозволяють" нам це?
Марко Топольник

@MarkoTopolnik Тому що це нам не заважає: D
Maroun

8
@MarounMaroun Але які міркування не заважають нам?
Марко Топольник

@Marko Java дозволяє мати кілька класів, визначених в одному файлі (якщо лише один з них є загальнодоступним). Оскільки всі класи в одному пакеті повинні мати інше ім'я, немає іншого варіанту, крім того, щоб дозволити непублічним класам мати інше ім'я, крім імені файлу.
isnot2bad

2
Мої 2 копійки: можливо, він був розроблений таким чином для швидшої локалізації занять всередині classpath. З цією умовою перевірка імен файлів / шляхів є достатньою для виявлення класу. Без цієї конвенції завантажувач класів classpath може знадобитися відкрити та розібрати файли, щоб знайти класи
Андрій Нікусан

13

Я думаю, що дозволити їх є необхідною умовою для вкладених класів. Зокрема, анонімні класи різко зменшують кількість необхідних файлів .java. Без підтримки цього вам знадобиться безліч реалізацій інтерфейсу одного методу у власних окремих файлах від основного класу, в якому вони використовуються. (Я думаю про слухачів дій, зокрема)

Існує гарне пояснення всіх вкладених класів в класів Вкладені Java підручник на веб - сайті Oracle, яка має приклади кожного з них. Також є причина, чому вони корисні, яку я цитую:

Навіщо використовувати вкладені класи?

Основними причинами використання вкладених класів є наступне:

  • Це спосіб логічного групування класів, які використовуються лише в одному місці : Якщо клас корисний лише одному другому класу, то логічно вбудувати його в цей клас і тримати їх разом. Введення таких "помічницьких класів" робить їх пакет більш впорядкованим.

  • Це збільшує інкапсуляцію : Розгляньте два класи вищого рівня, A і B, де B потрібен доступ до членів A, які в іншому випадку будуть оголошені приватними. Приховуючи клас B у класі A, члени A можуть бути оголошені приватними, і B може отримати доступ до них. Крім того, сам Б може бути прихований від зовнішнього світу.

  • Це може призвести до більш читабельного та легкодоступного коду : Введення невеликих класів у класах верхнього рівня розміщує код ближче до місця його використання.

(наголос мій)

Я не знайомий з специфікаціями Java ще в перші дні, але швидкий пошук показує, що внутрішні класи були додані в Java 1.1.


Що робити у випадках, коли тип корисний лише для іншого типу, але екземпляри першого типу не пов’язані з екземплярами другого?
supercat

Вкладені класи - це спосіб Java 1.2 виконувати лямбди або "Функції першого класу, коли все є об'єктом". Це змінюється у синтаксисі 1,8. Вони також використовуються, коли ми хочемо моделювати алгебраїчні типи даних у системі Type Java.
хокі

12

Я дивлюся на це навпаки. Природний стан речей полягав би в тому, щоб програміст самостійно обирав і ім’я класу, і ім’я файлу. Можливо, для спрощення пошуку публічних класів поза пакетом під час компіляції існує спеціальне обмеження, щоб публічний клас містився у файлі з відповідним іменем.


4

Зауважте, що Java відрізняється від регістру, але файлова система не повинна бути. Якщо базове ім'я файлу "abcd", але клас "Abcd", чи відповідає це правилу файлової системи, нечутливої ​​до регістру? Звичайно, не, коли вони переносяться на чутливі до регістру.

Або припустимо, у вас трапився клас під назвою ABCD, і клас Abcd (давайте не будемо вникати в те, що це погана ідея: це може статися), і програма переноситься на файлову систему, нечутливу до регістру. Тепер вам потрібно не лише перейменовувати файли, але й класи, ой!

Або що робити, якщо файлу немає? Припустимо, у вас є компілятор Java, який може приймати дані на стандартному вході. Тож клас повинен бути названий "StandardInput"?

Якщо ви раціонально досліджуєте наслідки того, як вимагати від імен файлів слідувати іменам класів, ви виявите, що це погана ідея більш ніж одним способом.


Я погоджуюся з тим, що ви маєте сказати, але не знаю, що це особливо відповідає на питання, за винятком можливо, наскільки деякі проблеми, пов'язані з архітектурою імен, можна було б полегшити, дозволяючи іменам непублічних класів відрізнятися від назви файлів. До речі, що стосується випадку чутливості, якщо я отримання мови, в будь-якому обсязі були Fooбуло оголошено, ідентифікатори FOO, foo, fOoі т.д. б все «не визначені» , навіть якщо б вони існували в межах зовнішніх областей. Така конструкція дозволила б усунути питання чутливості до регістру для імен файлів.
supercat

3

Ще одним моментом, на який пропущено багато відповідей, є те, що без publicдекларації JVM ніколи не дізнається, які основні методи класів потрібно використовувати. Усі класи, оголошені в одному файлі .java, можуть мати основні методи, але основний метод запускається лише для класу, позначеного як загальнодоступний. HTH


0

Оскільки файл java може містити більше одного класу, він може мати два класи в одному файлі java. Але файл java повинен містити клас як те саме ім'я, що і ім'я файлу, якщо він містить загальнодоступний клас.


Ні, це правило застосовується лише для громадських занять.
мертвий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.