web-dev-qa-db-ja.com

Java 9では、パッケージとモジュールが別々の概念であるのはなぜですか?

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

モジュールとパッケージは、意味的に分離した概念を表していますか? any言語(関心の分離)の両方に両方を使用することが賢明であることを意味します。またはJavaには、下位互換性への賛辞として両方が必要ですか?

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


JSR 376 : "Javaプラットフォームモジュールシステム"プロジェクト内に実装 Jigsaw

[〜#〜] sotms [〜#〜] によると

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

JLSはパッケージの定義を慎重に避けています。 Wikipedia から:

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

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

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

22
user2418306

モジュールの概念は、その概念のインスタンス化とは異なります。

Javaには常にモジュールがありました。メソッドはモジュールであり、クラスもパッケージも同様です。モジュールは、内部の詳細が隠されている組織の単位であり、合意された契約を介して他のモジュールと通信します。たとえば、メソッドは非表示の内部(コードとローカル変数)とコントラクト(パラメーターと戻り値の型)を持っているため、モジュールです。モジュールは、下位レベルのモジュールから構成できます。クラスにはメソッドが含まれます。

コアに不足しているものJava(pre-9)はdeployableモジュールです。上記のすべての種類のモジュールは、コピー可能なデプロイ可能なユニットではありませんJavaにはJARファイルと呼ばれるデプロイ可能なアーティファクトはありますが、カプセル化もコントラクトもないため、これらはモジュールではありません。実行時にJARファイルが消え、すべてが1つの「クラスパス」にマージされます。 。

OSGi は、「バンドル」の概念を使用して、1998年にデプロイ可能なモジュールの欠如に対処しました。これらは物理的にJARファイルであり、パッケージが含まれていますが、OSGiはランタイムシステムとともに追加のメタデータを定義して、そのレベルでのカプセル化とコントラクトをサポートします。

Java 9は、OSGiと同様の方法で、デプロイ可能なモジュールの欠如に対処します。 OSGiが存在して機能しているので、おそらくこれは完全に不要でしたが、それはまったく異なる議論です...

残念ながら、Java 9は、新しいモジュールの概念を単に「モジュール」と命名することで水を汚します。これは、メソッド、クラス、およびパッケージがモジュールでなくなることを意味しません!J9「モジュール」は、単なる別のインスタンス化です。モジュールのconceptです。OSGiバンドルと同様に、J9モジュールはパッケージから作成され、コピーできる物理的なアーティファクト(通常はJARファイル)です。ランタイムシステムは、それらを具現化します。

概要:はいJ9モジュールとパッケージは、意味的に分離した概念です。明らかにJavaは、下位互換性のために既存のパッケージの概念を保持する必要があります。Wordの「パッケージ」は、Javaと他の言語またはRPMのようなパッケージ管理システム。新しいJ9モジュール(およびOSGiバンドル)は、RPMのパッケージにJava以前のパッケージよりも)はるかに似ています。

22
Neil Bartlett

答えを危険にさらしますが、その多くは仮定/髪の毛の分割/怒鳴りなどかもしれません。

それらは同じものですか?さて、はい そして 番号

"Java 9"のモジュール性]に関するこのJavaWorldの記事 から:

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

パッケージは、あるレベルの抽象化をJavaプログラミングランドスケープに追加しようとします。これらは、固有のコーディング名前空間および構成コンテキストのための機能を提供します。しかし、悲しいことに、パッケージの規則は簡単に回避され、頻繁に危険なコンパイル時のカップリング。

@ser2418306(OP) ヒントあり "モジュールは正しく行われたパッケージ "。 Java(Java 9の時点で)のモジュールとパッケージ)は(OPが尋ねるように)意味的に同じことです。つまり、これらは事前にコンパイルされたJVMバイトコードのコレクションであり、他のメタデータ-essentially、それらはライブラリです。

さて、違いは何ですか?

ただし、違いはそれぞれの内部のmetadataです。 Java packageマニフェスト、またはJARマニフェストは、多くの場合、ライブラリ開発者によって維持されておらず、JAR /パッケージが提供するものに関して確実な契約も提供していません。 ここで説明(JavaWorldの記事)

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

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


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

もう1つの領域 その記事で説明 は、ビルドプロセスの一部として依存関係を管理する Maven などのシステムです。 Apache Mavenサイトのこのページ から:

依存関係管理:

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

今、私がそこにいるように未来について話します

そのページ で述べたように、他の言語(Perlなど)にはパッケージリポジトリがあります( [〜#〜] cpan [〜#〜] など)。これは、過去10年間程度、増加傾向にあります(私はそのように感じるので、はっきりとした証拠はありません)。 Rubyの gems 、Pythonの PyPi 、および Nodeパッケージマネージャー(npm などのツールは、これに基づいて一貫性を提供します正しいstuff(パッケージ、モジュール、gem、gizmoなど)を使用して環境(開発、ビルド、テスト、またはランタイムなど)を構成する方法。 "借りたアイデア(私は感じます)は借りました"Linuxディストリビューションシステム(Debianの apt 、RedHatのrpmなど)から(ただし、明らかに、少なくともone世代、そしてこれらのことをすべてより良くしました。)


Javamodules、ただし、必ずしもまだ実行できないことを追加するわけではありませんが、依存関係/パッケージ管理および自動ビルド環境用のツールをすべて作成します[ 〜#〜]ずっと[〜#〜]簡単です。それがモジュールを「より良く」するかどうか、私は断る。 :P

10
Tersosauros