保護されたメソッドへのアクセスを、同じパッケージ内のクラスではなく、任意のパッケージ内のサブクラスのみに制限するにはどうすればよいですか。
サブクラスではなく、同じパッケージ内にあるクラスも、「保護されたメソッド」のような例外をスローする必要があります。
編集:呼び出しクラス名インスタンスをチェックする方法はありますか?その後、instanceofを使用して確認できます。
保護されたメソッドへのアクセスを、同じパッケージ内のクラスではなく、任意のパッケージ内のサブクラスのみに制限するにはどうすればよいですか。
サブクラスではなく、同じパッケージ内にあるクラスも、「保護されたメソッド」のような例外をスローする必要があります。
編集:呼び出しクラス名インスタンスをチェックする方法はありますか?その後、instanceofを使用して確認できます。
それは不可能。protected
修飾子(同じパッケージ内のサブクラス+クラス)とデフォルトの修飾子(同じパッケージ内のクラス)のどちらかを選択できます。3番目のオプションはありません。
また、呼び出し元のコードのクラス名とパッケージを見つけるのは簡単ではないため、実行時にそれを簡単に強制することはできません。参照:スタックトレースまたはリフレクションを使用してメソッドの呼び出し元を見つけるにはどうすればよいですか?
1つのオプションはaspectjを使用することです。コンパイル時にprotected
、サブクラスではないときに同じパッケージからメソッドにアクセスしようとするコードを拒否することもできます(declare warning
とdeclare error
ディレクティブの助けを借りて)。おそらく、のようなコンパイル時のアノテーションを含めたいと思うでしょう@SubclassesOnly
。参照:コンパイル時のアーキテクチャーの実施の再検討:AspectJ、Maven、Eclipse、およびAspectJを使用したコンパイル時のチェック。
簡単:パッケージから他のすべてのクラスを削除し、基本クラスのみを残します。
つまり、クラスにアクセスできるクラスは別のパッケージからのものだけです。
別のライブラリがパッケージ名をコピーする場合、呼び出し元のパッケージを簡単に確認して、自分のパッケージと同じではないと断言できます。
if (getClass().getPackage().equals(MyBaseClass.class.getPackage())
throw new IllegalAccessError(); // or similar
参考までに、サブクラスのクラスとなるのgetClass()
クラスを提供します。this
呼び出し元のクラスを見つけるには、次のコードを使用します。
Class<?> callerClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());