6

私は2つのJavaパッケージAとBを持っています.パッケージBのいくつかのクラスがパッケージAのいくつかのクラスを使用したいとしましょう.しかし、開発者が来てパッケージC(または、アプリケーションC)を開発すると、彼/彼女は私のパッケージ Bを使用しますが、B が使用している A のクラスを彼/彼女に使用させたくありません。つまり、パッケージ A のクラスをパッケージ プライベートにして、アプリケーション開発者から隠されるようにしたいということです。ただし、私自身のパッケージ B がパッケージ プライベートであるクラスにアクセスできるようにしたいと考えています。これは Java で実行できますか? 基本的に、弾丸を噛んでクラスを公開し、ユーザーがそれらを使用しようとしないことを願うだけですか? または、A にあるクラスを B の中に複製する必要がありますか?

私の好みは、ハックではないものです (つまり、リフレクションを使用したくない)。ヘルプ?

4

2 に答える 2

6

JDK8とそのProjectJigsawでそれを行うことができます。ProjectJigsawクイックスタートガイドをご覧になることをお勧めします。

残念ながら、ジグソーパズルはJDK8の一部であり、まだ完全には準備ができていません。2013年1月まで機能が完了する予定はなく、2013年半ばまでにリリースされることはありません。

ただし、JDK 8プレビューを使用してクラスをコンパイルし、アイデアを機能させることはできます。

この場合、アプリケーションを独立したモジュールに分割することで問題を解決できます。あなたは次のようなことをすることができます:

module foo {
    exports foo;
    permits bar;
    permits baz;
}

ここで、モジュールfooは、barまたはbazという名前のモジュールでのみ必要です。他の名前のモジュールからfooへの依存は、コンパイル時、インストール時、または実行時に解決できません。許可句が存在しない場合、そのような制約はありません。

ApacheFelixEclipseEquinoxに実装されているOSGIのような代替フレームワークが、これらのレベルのカプセル化を実装するための何らかの機能を提供しているかどうかはわかりません。それについて少し調べたいと思うかもしれません。

Jigsawが存在しないOSGiの問題は、フレームワークによって適用されるルールがリフレクションによって破られる可能性があることです。ただし、Jigsawが一般に使用できるようになると、これらのルールは、コンパイル時にJava自体によって適用されます。 、ランタイムおよびインストール時間。

于 2012-06-12T02:54:15.953 に答える
2

OSGi でこれを行うことができます。この場合、ターゲットとしての Android と JDK 6 は問題ではありません。Android で実行されている OSGi フレームワークがあります。たとえば、Android 用の mBedded Server を参照してください。リンクから無料の非商用版をダウンロードできます。

達成したいことに応じて、OSGi でそれを行う方法がいくつかあります。

オプション 1 (推奨): パッケージ A と B を 1 つの同じバンドル AB に配置し、Export-Package を使用してこのバンドルのマニフェストでパッケージ B のみをエクスポートできます。パッケージ/アプリケーション C またはその他の「ユーザー」アプリは、パッケージ B をインポートして使用できます。また、パッケージ A はバンドル AB の内部であるため、使用できず、パッケージ A も表示されません。Java レベルでの特別な宣言や依存関係は必要ありません。これは、モジュール性と個別のバンドル スペースが OSGi の基本の一部であり、最新の Java バージョンや機能に依存しないため、任意の Jva バージョンで機能します。

オプション 2: 何らかの理由でパッケージ A と B を別々のバンドルに分けたい場合は、パッケージをマニフェストでエクスポートおよびインポートし、アクセス許可を使用して、どのバンドルがどのパッケージをインポートする権利を持つかを制御します。 (OSGi Permission および Conditional Permission サービスを参照してください)。ただし、これを実現するのはより複雑です。

オプション 3: パッケージ A をフラグメント バンドルに入れ、B を含むバンドルにアタッチできるようにすることもできます。この方法では、B はパッケージ A にアクセスできますが、同時にパッケージ A を個別に更新することもできます。必要に応じて実行時に。フラグメント内のパッケージはホスト バンドルのプライベートとして扱われるため (この場合、ホストはパッケージ B を含むバンドルです)、バンドル C は A を認識しません。バンドル B によってエクスポートされたもののみを認識します。

あなたは OSGi にあまり詳しくないので、オプション 1 から開始することをお勧めします。その後、必要に応じてオプション 3 にアプローチをアップグレードできます。

@Edwin Dalorzo : OSGi のルールがリフレクションによって破られる可能性があるというのは、絶対に真実ではありません。バンドルには、OSGi に別個のクラスローダーがあります。クラス A ではできないのと同じくらいバンドル C から反映することができ、取得する唯一のものは ClassNotFound 例外です - 私を信じてください、私はそれを十分に見てきました ;)

于 2012-06-14T10:34:20.983 に答える