パッケージとモジュールがJava 9で別個の概念である理由


21

Java 9には、パッケージに加えてモジュールがあります。通常、言語にはどちらか一方があります。そして、ほとんどのプログラマー 2つの用語を同義語として認識しています。モジュールはパッケージの上に構築され、それらをプリミティブとして扱います。複合パターンは、プリミティブと複合物を均一に処理することを提案します。そうしないと、悪いことが起こります。たとえば、プロジェクトValhallaを見てください。そこでは、プリミティブ(値)および参照型の共通スーパータイプを後付けしようとしています。

モジュールとパッケージは意味的に分離した概念を表していますか?それを意味することの両方を持つことが賢明である任意の言語(関心事の分離)。または、Javaは後方互換性への賛辞として両方を持たなければなりませんか?

既存の概念を補強するのではなく、なぜ新しい概念を導入するのですか?


JSR 376:プロジェクトJigsaw内に実装された「Javaプラットフォームモジュールシステム」。

SOTMSによると

モジュールは、コードとデータの名前付きの自己記述型コレクションです。そのコードは、Javaクラスとインターフェースなどのタイプを含むパッケージのセットとして編成されています。そのデータには、リソースおよびその他の種類の静的情報が含まれます。

JLSは、パッケージとは何かを定義することを慎重に避けますウィキペディアから:

Javaパッケージは、JavaクラスをModulaのモジュールに似た名前空間に編成するための手法で、Javaでのモジュール式プログラミングを提供します。

ウィキペディアを引用するのは悪い習慣であることは知っていますが、それは一般的な理解を反映しています。モジュラープログラミングのエントリから:

パッケージという用語は、モジュールの代わりに使用されることがあります(Dart、Go、またはJavaなど)。他の実装では、これは明確な概念です。Pythonではパッケージはモジュールのコレクションですが、今後のJava 9では新しいモジュールの概念(強化されたアクセス制御を備えたパッケージのコレクション)の導入が計画されています。


3
ここで一緒にたくさんの質問をしていると思いますか?1)モジュールとパッケージは同じセマンティックアイデアですか?2)(1ではない場合)、- jigsawstyleモジュールは単なるパッケージの技術的な改善ですか?3)(1ではない場合、および2である場合)、Javaは単純に(または一見)下位互換性のために両方の概念を保持します。これらの質問の一部は回答可能であり、一部は主に意見志向です。ここでは、求めている明確化を簡素化する編集が整頓されていると思います。
テルソサウルス

1
@Tersosauros「一部の」質問をトピック外として分類しましたが、どちらがどれであるかをラベル付けしませんでした。私はそれをただ一つの質問だと思っています(1)。その他は自動的に解決されます。Javaの下位互換性は問題ではありません。したがって、Javaがパッケージデザインの欠陥を修正するためにモジュールを導入したか、2つの概念はまったく別の問題です。そして、混乱は悪い命名によるものです。
user2418306

1
質問をもっと明確にしたい。しかし、あなたはそれのどの部分が答えられないと思うかを理解する必要があります。1つの部分しかないと思うとき。
user2418306

ああ、私は混乱を理解しています。質問#1 答えられると思います(その答えは「はい、しかしいいえ」です-これが#3の出番です)。私は#3について同意します、明らかにJavaはJREの言語キーワードのような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バンドル)は、JavaパッケージよりもRPMのパッケージによく似ています。


パッケージがモジュールの定義を満たしていません。カプセル化が弱く、他のパッケージを集約して可視性を改善する手段がないため。クラスには、ネストされたクラスまたはフィールドを含めることができます。メソッドにはクロージャーを含めるか、他のメソッドを呼び出すことができます。パッケージは他のパッケージと「通信」できません。
user2418306

同意しません。パッケージには情報が隠されています(デフォルトのアクセスタイプ、メソッド、フィールド、別名package-private)。パッケージ内のコードは他のパッケージのコードを呼び出すことができるため、パッケージは確かに「通信」します。これは、契約、つまり他のパッケージのパブリックタイプとメソッドに対して行われます。
ニールバートレット

同じレベルでモジュラーアーティファクト(クロージャを含むメソッド、ネストされたクラスを含むクラスなど)を集約する機能は、モジュールの定義の一部を形成しないことに注意してください。これをモジュール定義の必要な部分と考える場合、「Java 9モジュール」もモジュールではありません。
ニールバートレット

パッケージに情報が隠れていることを否定しません。十分ではないと言いました。importパッケージを結合できます。しかし、パッケージをファーストクラスの市民として構成する方法はありません。これらの欠点(およびOSGiの制限)は、JSR 376で説明されています
。– user2418306

Java 9モジュールもモジュールではない理由を詳しく説明できます
user2418306

10

その多くは仮定/分割髪/暴言などかもしれませんが、答えを危険にさらしてみましょう

それらは同じものですか?まあ、はいいいえ

「Java 9のモジュール方式」に関するこのJavaWorldの記事から:

モジュラーソリューションとしてのパッケージ

パッケージは、Javaプログラミング環境に抽象化のレベルを追加しようとします。独自のコーディング名前空間と構成コンテキストの機能を提供します。ただし、残念ながら、パッケージの規則は簡単に回避され、コンパイル時の危険な結合の環境につながることがよくあります。

@ user2418306(OP)ほのめかし、モジュールが正しく行わパッケージです。Javaのモジュールとパッケージ(Java 9の時点では明らかに)は(OPが要求するように)意味的に同じです。つまり、これらはプリコンパイルされたJVMバイトコードのコレクションであり、他のメタデータとともに - 基本的にはライブラリです。

さて、違いは何ですか?

ただし、違いはそれぞれのメタデータにあります。Java packageマニフェスト、またはJARマニフェストは、ライブラリ開発者によって維持されることはあまりなく、JAR /パッケージが提供するものに関する確実な契約も提供しません。ここで説明したように(JavaWorldの記事をもう一度)

JARファイルはモジュール化されていませんか?

JARファイルとそれらが動作するデプロイメント環境は、他の方法で利用可能な多くのレガシーデプロイメント規則を大幅に改善します。ただし、JARファイルには、まれにしか使用されないバージョン番号は別として、固有の固有性はありません。JARファイルとオプションのマニフェストは、Javaランタイム環境内のモジュール性規則として使用されません。したがって、ファイル内のクラスのパッケージ名とクラスパスへの参加は、ランタイム環境にモジュール性を与えるJAR構造の唯一の部分です。


他の言語/環境などに関する暴言

その記事で議論された別の分野は、ビルドプロセスの一部として依存関係を管理するMavenなどのシステムです。Apache Mavenサイトのこのページから:

依存関係管理:

Mavenは、JARおよびその他の依存関係の中央リポジトリの使用を推奨しています。Mavenには、プロジェクトのクライアントがPerlのCPANのように中央のJARリポジトリからプロジェクトのビルドに必要なJARをダウンロードするために使用できるメカニズムが付属しています。これにより、Mavenのユーザーはプロジェクト間でJARを再利用でき、プロジェクト間の通信を促進して、後方互換性の問題に対処できるようにします。

今、私がそこにいたかのように未来について話す

そのページで述べたように、他の言語(Perlなど)にはパッケージリポジトリ(CPANなど)があります。これは、過去数十年ほどにわたって増加傾向にあります(私は、私がそれを感じているので、何の重要な証拠もありません)。Rubyのgem、PythonのPyPiNodeパッケージマネージャー(npmなどのツールはこれに基づいて構築され、適切なもの(パッケージ、モジュール、宝石、ギズモなど)。アイデア(私が感じる)は借用などでした(明らかに、少なくとも1世代は進化しており、これらはすべてより良いものになりました。)など、DebianのようLinux®の配信システムからのapt、RedHatのrpm


Javaは、モジュール、彼らは必ずしも依存関係/パッケージ管理および自動ビルド環境のためのメイクツールはすべて、あなたがまだできないことは何も追加しませんがMUCH容易になります。それがモジュールを「より良くする」かどうか、私は言いません。:P


1
記事は1年前のものですが、すでに廃止されています。それは、バージョン管理がモジュールの基本的な特性である方法を説明します。ジグソーモジュールにはバージョン情報がありません。エンドユーザーにとって、依存関係管理の領域では何も変わりません。ビルドツールの場合、実際には事態はずっと難しくなります。彼らは平行現実をセンターサポートする必要があるとして、classpathそしてmodulepath。そして、ユニットテストをサポートするためにフープをジャンプします。2つの概念は、物のコレクションとメタデータを表すので、私が受け入れるにはあまりにも大胆すぎるため、2つの概念は同等であると仮定します。さらに、途中で突然jarをパッケージに置き換えました。
-user2418306

2つの概念は同等」とは言わなかったが、「概念的には同じもの」だと言った。また、あなたは私がして答えたので、質問編集した特別JSR-376に言及し、などに反対するジグソー以前言われていたものです: - /
Tersosauros

JigsawにはJSR-376が含まれます(実装)。質問はまだ両方にリンクしているため、害はありませんでした。辞書は、同等性を同じ意味を持つ品質または状態として定義します。そして意味的に-意味に関して。申し訳ありませんが、ここで間違った詳細についてped慢に思っています。あなたはそれらが同等であると言いました。しかし、あなたは推論を提供しませんでした。代わりに、パッケージとjarがモジュールに失敗する方法を説明する記事を参照してください。しかし、今後のモジュールも記事のモジュールではありません。同等性を主張し、2(3)の違いを提供することは自己矛盾しています。
user2418306

質問に対する答えは「はい」と「いいえ」にはできません。2つの概念が意味的に同等かそうでないか。コメントをロボット化せずに、元の質問に戻らないでください。言語には両方の概念が必要ですか、これはJavaレガシー固有の問題ですか?明確化が必要な場合は、喜んでお手伝いします。
user2418306
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.