2016-08-11 14 views
11

JigsawプロジェクトのコアはJava Module Systemなので、特定のモジュール内の特定のプログラム要素(クラス、メソッド、フィールド)へのアクセスを制限することができれば便利です。Java 9の「モジュールローカル」アクセス動作

モジュールに本質的にパブリックな要素がいくつかありますが、このモジュールの外ではアクセスできないようにすると便利です。

私は、 "package-local"の後に次のレベルのアクセスを話しています。これは "module-local"という名前でもかまいません。

ただし、Jigsaw rulesを一見してみてください。初期の仕様は、この種の機能を理解するのに役立ちませんでした。具体的にはthis Modifier specificationには新しい要素が含まれていません。

将来のJava 9でこれを行う可能性はありますか?

+0

私の理解によれば、モジュールはデフォルトでは閉じられています。あなたは明示的に物を輸出して、物を外部から必要とするようにしなければなりません。 http://openjdk.java.net/projects/jigsaw/quick-startおよびhttps://en.wikipedia.org/wiki/Java_Module_System。あなたがここで尋ねていることを誤解していますか? – Gimby

+0

[モジュールシステムの状態](http://openjdk.java.net/projects/jigsaw/spec/sotms/)によれば、エクスポートされたパッケージのみがモジュール外で利用可能です。たとえば、[このテーブル](http://stackoverflow.com/questions/215497/in-java-difference-between-default-public-protected-and-private/33627846#33627846)も参照してください。 – aioobe

+0

@Gimbyあなたは正しいです:特定のパッケージをエクスポートすることは可能です。しかし、方法や分野はどうですか?はい、私はあなたが私の質問をかなり理解していると思います。 – Andremoniy

答えて

10

非エクスポートパッケージにpublic要素(すなわち、クラス、インタフェース、メソッド、またはフィールド)は、実際に、ある「ローカルモジュール。」それは内の他のすべてのコードにアクセス あろうモジュールではなく、 モジュールの外側からではありません。

エクスポートされたパッケージにmodule-local要素を宣言する方法はありません。 エクスポートされたパッケージのpublic要素は、 モジュールの外部からアクセスできますが、package-private要素はpackage-privateであり、これらの2つのモード間には要素レベルのアクセスモードはありません( )。 という新しいモードを定義することもできましたが、魅力的なユースケースはほとんど見つかっておらず、 さらに、エクスポートされたパッケージより細かい単位で のJVMでモジュラーアクセス制御を実装すると、かなりのパフォーマンスがかかります。

+0

"しかし、私たちはそれに対して魅力的なユースケースはほとんど見ていない" - Javaの世界ではないと確信している。あなたは他の場所を見たことがありますか?スウィフトの些細な部分を構築したことで、私にとって、「内部」の欠如はモデリング/設計に関するモジュールの潜在的な利点のほとんどを打ち破っています。私たちのユースケース:暗号鍵を持つ 'User'" resource "。 'User'はpublicですが、キーはモジュールプライベートである必要がありますが、package-privateである必要はありません。インターフェイスを公開するだけで対処しなければならないと思いますが、期待していない方法で実装する可能性のあるユーザーに対処しなければなりません。 – Raphael

+0

サブクラス化でも同様の問題が発生します。 'final'はサブクラス*がどこでも*できないようにするため、モジュール内でサブクラス化できる型を宣言することはできませんが、その外にサブクラス化されないことは確実です。 (またはできますか?) – Raphael

+0

"エクスポートされたパッケージの粒度より細かいJVMでのアクセス制御" - モジュールはパッケージよりも_coarser_ですか?私は誤解したことがありますか? – Raphael

5

短い答え

これは、このモジュールのために、本質的に公開されていますモジュール内のいくつかの要素がある場合に役立つことができますが、このモジュールの外部アクセスできないようにしてください。

これはできません。 (単独で、モジュールシステムの手段を - 回避策があります。)

ロング回答の説明は用語Accessibility内にある

:でパブリック型を検討

Javaコンパイラと仮想マシンあるモジュール内のパッケージがにアクセス可能であり、第1のモジュールが第2のモジュールによって上記で定義された意味で読取り可能であるときにのみ他のモジュールのコードによってアクセス可能であり、第1のモジュールはそのパッケージをエクスポートする。 [...]

このようにアクセスできないモジュール境界を越えて参照される型は、プライベートメソッドまたはフィールドが使用できないのと同じ方法で使用できません。それを使用しようとすると、エラーが報告されます。コンパイラ、IllegalAccessErrorがJava仮想マシンによってスローされたり、IllegalAccessExceptionがリフレクション実行時APIによってスローされたりする可能性があります。 [...]

モジュールの境界を越えて参照されるメソッドまたはフィールドは、その意味でその囲み型にアクセスできる場合、およびメンバー自体の宣言もアクセスを許可する場合にアクセス可能です。

コンパイラ/ JVMがアクセスタイプ追加のメカニズムがを適用していないと認めると、エクスポートすることができます正確にどのようにして、パッケージを誰にさまざまな方法がありますが。そのメンバーはジグソーパズルの前と同じくらいアクセス可能です。

これは、(アクセシブルな型のパブリックメンバがアクセス可能であるため)アクセス可能な型のメンバをモジュール内で見ることができない(つまり、publicを必要とする)が、その外側にないことを意味します。

回避策

だから、将来のJava 9でそれを行うには、他の可能性はありますか?

はい。 :)

あなたは、世界にエクスポートするメソッドを定義するエクスポートされたパッケージに、Globalを持つことができます。次に、インタフェースまたはクラスのいずれかを持ってLocalGlobalを拡張し、必要なすべてのメンバーを追加します。キーはLocalでなければなりません。は輸出パッケージになります!

あなたのモジュールのAPIがGlobal -sを返すだけですが、それらをメソッドの引数として受け取らない場合、あなたはうまく行きます。内部的には常にLocalを使用してキャストしてください。

Global -sも受け入れている場合は、APIが返されたインスタンス(つまり、ユーザーが独自の実装を作成することは許可されていない)のみであることを明確に文書化する必要があります。これは禁止されているように聞こえるかもしれませんが、元の要求について懸命に考えるならば、それは同じ特性を持ちます。

関連する問題