Чому пакети та модулі - це окремі поняття в Java 9?


21

У Java 9 будуть додатково встановлені модулі. Зазвичай мови мають те чи інше. І більшість програмістів сприймають два терміни як синоніми. Модулі побудовані поверх пакетів, трактуючи їх як примітиви. Складений малюнок пропонує ставитись до примітивів та композитів рівномірно. Інакше трапляться погані речі. Наприклад, подивіться на проект Valhalla, де вони намагаються доопрацювати загальний супертип для примітивних (значення) та еталонних типів.

Чи модулі та пакети представляють семантично окремі поняття? Значення це має сенс мати як для будь-якого мови (поділ проблем). Або Java має бути обома як данина відсталому сумісності?

Навіщо вводити нову концепцію замість розширення існуючої?


JSR 376 : "Система модуля платформи Java", реалізована в рамках проекту Jigsaw .

За даними SOTMS

Модуль - це іменований, самоописуючий набір коду та даних. Його код організований у вигляді набору пакетів, що містять типи, тобто класи Java та інтерфейси; її дані включають ресурси та інші види статичної інформації.

JLS обережно уникає визначення того, що таке пакет . З Вікіпедії :

Пакет Java - це метод організації класів Java в простори імен, схожих на модулі Modula, що забезпечують модульне програмування на Java.

Я знаю, що цитування Вікіпедії - це погана практика, але вона відображає загальне розуміння. Від входу на модульному програмуванні:

Термін пакунок іноді використовується замість модуля (як у Dart, Go або Java). В інших реалізаціях це окрема концепція; у Python пакет - це сукупність модулів, тоді як у майбутньому Java 9 планується впровадження нової концепції модуля (колекція пакетів з розширеним контролем доступу).


3
Я думаю, ти тут разом задаєш багато питань? 1) Чи модулі та пакети є однаковою семантичною ідеєю? 2) (якщо не 1), чи jigsawмодулі стилю - лише технічне вдосконалення щодо пакетів? 3) (якщо не 1, а якщо 2), чи просто Java (або, здавалося б) зберігає обидва поняття для зворотної сумісності. Деякі з цих питань відповідають, деякі в першу чергу орієнтовані на думку. Я думаю, тут потрібна редакція, яка спрощує уточнення (-и), що шукаються.
Терсосаврос

1
@Tersosauros Ви «класифікували» деякі питання як позатематичні, але не вказали, яке саме. Я вважаю це лише одним питанням (1). Інші будуть вирішені автоматично. Відстала сумісність для Java - це не питання. Таким чином, або представлені модулі Java для виправлення недоліків дизайну пакунків, або два поняття є справді окремими проблемами. А плутанина пов’язана з поганим називанням.
user2418306

1
Я хочу зробити питання більш зрозумілим. Але мені потрібно зрозуміти, яка його частина, на вашу думку, є невимовною. Коли я думаю, що є лише одна частина.
користувач2418306

Ах, я розумію плутанину. Я думаю, що питання №1 є відповідає (що відповідь є «Так, але немає» - що, де # 3 приходить в). Я погоджуюся з приводу №3, очевидно, що Java не збирається змінювати те, що таке мовне ключове слово packageє / робить / означає, і не збираються змінювати на (скажімо це, досить жахливі) системи класових маршрутів в JRE. Питання №2, я вважаю, головним чином орієнтований на думку (це відповідає , але моя відповідь та хтось інший можуть відрізнятися, і ніхто з нас не обов'язково помиляється).
Терсосаврос

1
Спробуйте задати чітке запитання вперед, а потім надайте допоміжний матеріал.
Джей Елстон

Відповіді:


22

Поняття модуля відрізняється від конкретизації цього поняття.

У Java завжди були модулі. Метод - це модуль, клас - це також пакет. Модуль - це одиниця організації, в якій приховані внутрішні деталі, і яка спілкується з іншими модулями за допомогою узгоджених контрактів. Наприклад, метод - це модуль, оскільки він має приховані внутрішні (код та локальні змінні) та контракт (параметри та тип повернення). Модулі можуть складатися з модулів нижчого рівня, наприклад, класи містять методи.

Чого не вистачає в ядрі Java (до 9), це модуль розгортання . Всі перераховані вище види модуля не є розгортаються одиницями, які можна скопіювати навколо. У Java є артефакт, що розгортається, називається файлом JAR, але це не модулі, оскільки вони не мають інкапсуляції чи контракту: під час виконання файли JAR зникають, і всі вони об'єднуються в один "класний шлях".

OSGi вирішила відсутність модулів, що розгортаються в 1998 році, з концепцією "розшарування". Це фізично файли JAR і вони містять пакети, але OSGi визначає додаткові метадані разом із системою виконання для підтримки інкапсуляції та контрактів на цьому рівні.

Java 9 вирішує відсутність модулів, що розгортаються, аналогічно OSGi. Можливо, це було зовсім непотрібно, оскільки OSGi існує і працює, але це зовсім інша дискусія ...

На жаль, Java 9 замулює води, називаючи нову концепцію модуля просто "модулем". Це не означає, що методи, класи та пакети перестають бути модулями! "Модуль" J9 - це ще одна інстанція концепції модуля . Як і пакети OSGi, модулі J9 складаються з пакетів, і це фізичні артефакти (зазвичай файли JAR знову), які можна копіювати навколо. Система виконання їх розуміє і повторює.

Резюме: так, модулі та пакети J9 - це семантично окремі поняття. Очевидно, що Java повинна зберегти існуючу концепцію пакету для зворотної сумісності. Зауважте, що слово "пакет" в Java використовується зовсім інакше, ніж в інших мовах або в системах управління пакетами, такими як RPM. Нові модулі J9 (і пакети OSGi) набагато більше схожі на пакети в RPM, ніж коли-небудь пакети Java.


Пакет не відповідає вашому визначенню модуля. Через слабку інкапсуляцію та відсутність засобів для агрегації інших пакетів та покращення їх видимості. Класи можуть містити вкладені класи або поля. Методи можуть містити закриття або викликати інші методи. Пакети не можуть "спілкуватися" з іншими пакетами.
користувач2418306

Я не погоджуюсь. Пакети містять інформацію про приховування (типи доступу, методи та поля за замовчуванням, так само пакет-приватний). Пакети, безумовно, "спілкуються", оскільки код у пакеті може викликати код в інших пакетах. Це робиться проти контракту, а саме публічних типів та методів іншого пакету.
Ніл Бартлетт

Зауважте, що здатність агрегувати модульні артефакти на одному рівні (наприклад, методи, що містять закриття, класи, що містять вкладені класи) НЕ є частиною мого визначення модуля. Якщо ви вважаєте це необхідною частиною визначення модуля, то "модулі Java 9" також не є модулями.
Ніл Бартлетт

Я не заперечую, що пакети приховують інформацію . Я сказав, що це недостатньо. importможе пару пакетів. Але немає можливості структурувати пакунки як громадян першого класу. Ці недоліки (та обмеження OSGi) описані в JSR 376.
user2418306

Чи можете ви пояснити, чому модулі Java 9 також не є модулями ?
користувач2418306

10

Дозвольте мені загрожувати відповіддю, хоча велика частина цього може бути припущеннями / розщепленням волосся / відшаровування тощо.

Вони однакові? Ну так і ні

З цієї статті JavaWorld про "Модульність у Java 9" :

Пакети як модульне рішення

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

Як натякнув @ user2418306 (OP) , " модулі - це пакети зроблені правильно " . Модулі та пакети в Java (очевидно, як у Java 9) є (як запитує ОП) семантично те саме. Тобто це колекції попередньо складених байт-кодів JVM, з іншими метаданими - по суті , це бібліотеки .

Ну яка різниця?

Однак різниця полягає у метаданих всередині кожного з них. Java- packageманіфести, або JAR-маніфести, розробники бібліотек не підтримуються часто, а також не надають жодного впевненого контракту щодо того, що надає JAR / пакет. Як пояснено тут (стаття JavaWorld знову) :

Файли JAR недостатньо модульні?

Файли JAR та середовище розгортання, в яких вони працюють, значно вдосконалюються для багатьох наявних у встановленому порядку умов розгортання. Але файли JAR не мають внутрішньої унікальності, крім рідко використовуваного номера версії, який прихований у маніфесті .jar. Файл JAR та необов'язковий маніфест не використовуються як умови модульності в середовищі виконання Java. Тож назви пакетів класів у файлі та їхня участь у класному шляху є єдиними частинами структури JAR, які надають модульність середовищу виконання.


Шум про інші мови / середовища тощо

Ще однією областю, що обговорюється в цій статті, є такі системи, як Maven , які керують залежностями для вас в рамках процесу збирання. З цієї сторінки на сайті Apache Maven :

Управління залежністю:

Мейвен заохочує використання центрального сховища JAR та інших залежностей. Maven оснащений механізмом, який клієнти вашого проекту можуть використовувати для завантаження будь-яких JAR, необхідних для побудови вашого проекту, з центрального сховища JAR, подібно до CPAN Perl. Це дозволяє користувачам Maven повторно використовувати JAR у проектах та заохочує спілкування між проектами, щоб забезпечити вирішення проблем із сумісністю.

Тепер поговорити про майбутнє так, ніби я там був

Як зазначалося на цій сторінці , інші мови (наприклад, Perl) мають сховища пакетів (наприклад, CPAN ). Це тенденція, що зростає (я кажу, тому що я відчуваю, що це подобається, без жодних чітких доказів) протягом останнього ~ десятиліття або близько того. Інструменти, такі як дорогоцінні камені Ruby , PyPhon PyPi та менеджер пакетів Node ( npm) , надходять на це, щоб забезпечити послідовний спосіб налаштування середовища (або розробки, складання, тестування, або часу виконання тощо) на потрібні речі (пакети, модулі, дорогоцінні камені, штучки тощо). Ідея (я відчуваю) була " запозичена " з дистрибуційних систем Linux®, таких як Debian Apt , RedHat'srpmі т. д. (Хоча, очевидно, еволюціонувало щонайменше одне покоління, і зробило ці речі приємнішими.)


Java- модулі , хоча вони не обов'язково додають те, що ви вже не можете зробити, полегшують інструменти для залежностей / управління пакетами та автоматизованих середовищ збирання НАБАГО . Чи це робить модулі «кращими», я не хочу сказати. : P


1
Статтю лише 1 рік і вона вже застаріла. Докладніше описано, наскільки версія є основоположною характеристикою модуля. Модулі головоломки не матимуть інформації про версію. Ніщо в царині управління залежністю не зміниться для кінцевого споживача. Створювати інструменти все стане набагато складніше. Оскільки їм потрібно підтримувати паралельні реалії classpathта modulepath. І перестрибуйте через обручі, щоб підтримати тестування блоку. Припускаємо, що два поняття рівноцінні, оскільки вони представляють колекцію речей плюс метадані, я занадто сміливо приймаю. Плюс до середини ви несподівано замінили банку на пакет.
користувач2418306

Я не сказав " два поняття рівнозначні ", я сказав, що вони "семантично одне і те ж", - про що ви запитали. Крім того, ви відредагували це питання, оскільки я відповів, щоб конкретно згадати JSR-376 , як проти головоломки , про що було сказано раніше: - /
Tersosauros

Головоломка включає в себе (знаряддя) JSR-376. Питання все ще посилається на обидва, тому шкоди не було зроблено. Словник визначає еквівалентність як якість або стан такого ж значення. І семантично - щодо значення. Мені дуже шкода, але ти дуже пильнуєш неправильні деталі. Ви сказали, що вони рівноцінні. Але ви не надали жодних міркувань. Натомість ви посилаєтесь на статтю, яка пояснює, як пакунки та банки не є модулями. Але майбутні модулі теж не є модулями зі статті. Затвердження еквівалентності, а потім надання різниці між 2 (3) самосуперечливо.
користувач2418306

Відповідь на запитання не може бути так і ні. Або два поняття, семантично еквівалентні, або ні. Будь ласка, не лоботомізуйте мої коментарі та поверніться до оригінального питання. Чи потрібні мови обидва поняття, або це специфічне питання спадщини Java? Якщо вам потрібні роз'яснення, я радий допомогти.
користувач2418306
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.