3

Java では、実行時にリフレクションを使用してプライベート フィールドにアクセスしたり、リフレクションを使用してプライベート ネスト/内部クラスにアクセスしたりできます (たとえば、こちらを参照)。Java がこのようになっている理由を説明する特定の技術的理由、または一般的な設計哲学はありますか? わかりませんが、これを読むと、少なくとも一部の構成では、C#/.NET のように見えますが、同じことは不可能です。Javaにもその柔軟性がありますか? これが不可能な JVM 実装はありますか?

もちろん、Java がリフレクションを介したプライベート フィールドへのアクセスを許可していない場合でも、いつでも独自のランタイムを記述して、好きなことを行うことができます。または、バイナリ .jar/.class ファイルを変更して、アクセス修飾子を変更することもできます (これは可能だと思います)。

したがって、Java の設計者が選択しなければならなかった 3 つの可能性があるようです。

  1. プライベート フィールドへの直接アクセスを許可します...おそらく警告が表示されます。
  2. プライベート フィールドへの直接アクセスを許可しないでください。ただし、リフレクションを使用してプライベート フィールドへのアクセスを許可してください。
  3. プライベート フィールドへの直接アクセスを許可しないでください。また、リフレクションを使用したプライベート フィールドへのアクセスも許可しないでください。プライベート フィールドにアクセスする唯一の方法は、ランタイムを変更するか、バイナリの .jar/.class ファイルをオフラインで変更することです。

真ん中のものを選ぶのは恣意的に思えます...目標ができるだけ不便にすることである場合、選択肢3が最適です。とにかく真に防止できないものに人為的な不便を加えないことが目標である場合は、1 が最適です。

言語またはランタイムについて、選択肢 2 を選択する決定を通知または強制したものはありますか?

4

2 に答える 2

2

ある意味では、リフレクションの使用はまさに #1 で探している警告ではありませんか?

リフレクションを使用すると、退屈な問題を洗練された方法で解決できる場合があります。GSON ライブラリがオブジェクトを作成および設定する方法が良い例です。「通常の」コードはこれらのプライベート フィールドにアクセスすべきではありません。リフレクションを使用するとアクセスできますが、例外処理とアクセス許可の変更に必要なすべてのオーバーヘッドがあり、これが一般的なケースで行われるものではないことを明確にします。

リフレクションは、単にプライベート フィールドにアクセスするよりもはるかに多くの機能を提供します。実行時に、コンパイル時に知ることができないクラスとオブジェクトに関するデータを検査し、それらを使用してメソッドを呼び出し、コードがコンパイルされたときに存在しなかったフィールドにアクセスできます。その動作のサブセットはプライベート アクセスです。

そうです、Java 設計者は、プライベート アクセス用のある種の構文を作成することもできましたが、リフレクションも作成する必要がありました。これは、プライベート データにアクセスするためのより論理的で強力な方法です。ただし、この動作は注意して使用する必要があることを (単純に複雑なため) 明確にしています。私にとって、単に電話をかけるobject.privates.fieldなどのことは、同じ重大度を意味するものではありません。

于 2013-08-14T20:23:04.457 に答える
0

単体テストのためにプライベート フィールドにアクセスする必要がある場合があります。内部で使用されているが直接呼び出されるべきではないクラスで小さなプライベート関数をテストする場合など。また、内部データ構造に正しいデータが含まれているかどうかを確認したい場合もあります。

他の理由でプライベート データにアクセスする手段としてリフレクションを使用している場合は、コードをレビューしているほとんどの人 (存在する場合) がおそらく気づき、赤で表示されるため、おそらくそうする正当な理由を考え出す必要があります。フラグ (フィールドは理由でプライベートですよね?)。

選択肢 2 はおそらく、このリフレクションの使用を許可するために行われたものです (非デバッグ ビルドでは無効にすることができます)。

于 2013-08-14T20:21:46.403 に答える