[解決済み] リフレクション使用時にIllegalAccessExceptionが発生する。
2022-02-18 14:27:56
質問
リフレクションを学ぼうとしていたところ、このIllegalAccessExceptionに遭遇しました。以下のコードをご覧ください。
public class ReflectionTest
{
public static void main(String[] args)
{
Set<String> myStr = new HashSet<String>();
myStr.add("obj1");
Iterator itr = myStr.iterator();
Method mtd = itr.getClass().getMethod("hasNext");
System.out.println(m.invoke(it));
}
}
このプログラムを実行しようとすると、次のようになりました。
Exception in thread "main" IllegalAccessException
何が起こっているのか理解できない。何かアイデアはありますか?よろしくお願いします。
解決方法は?
setAccessible(true)を指定して、他のクラスのプライベートメソッドを反射的に呼び出すには、Java言語によるアクセスチェックを抑制する必要があります。
Method mtd= itr.getClass().getMethod("hasNext");
if(!mtd.isAccessible()) {
mtd.setAccessible(true);
}
さらに、SecurityManagerがenableの場合、setAccessible(true)を呼び出すために特別なパーミッションが必要です。 そうでなければ、我々は得る。
C:\ReflectionTest>java -Djava.security.manager CallFoo
Exception in thread "main" java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:107)
at CallFoo.main(CallFoo.java:8)
この suppressAccessChecks 権限は、信頼できるコードソースにのみ与えたいのであって、コールスタック内のすべてのクラスには絶対に与えないでください。 そこで、CallFoo.javaを修正します。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
public class CallFoo {
public static void main(String args[]) throws Exception {
doCallFoo();
}
public static void doCallFoo() throws IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, InstantiationException, PrivilegedActionException {
Class fooClass = Class.forName("Foo");
final Foo foo = (Foo) fooClass.newInstance();
final Method helloMethod = fooClass.getDeclaredMethod("hello");
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
if(!helloMethod.isAccessible()) {
helloMethod.setAccessible(true);
}
helloMethod.invoke(foo);
return null;
}
});
}
}
関連
-
[解決済み】javaで指定されたファイルが見つからない
-
[解決済み] JavaでSSLピアが正しくシャットダウンされない
-
[解決済み] リフレクションを使用して文字列からプロパティ値を取得する
-
[解決済み] Mavenを使用して、依存関係を持つ実行可能なJARを作成するにはどうすればよいですか?
-
[解決済み] リフレクションとは何か、なぜ有用なのか?
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] リフレクションを使ってジェネリックメソッドを呼び出すにはどうしたらいいですか?
-
[解決済み] C#のリフレクションで型がインターフェースを実装しているかどうかを判断する方法
-
[解決済み] リフレクションを使って、パッケージ内のすべてのクラスを見つけることができますか?
-
[解決済み] Javaリフレクションを用いた静的なプライベートfinalフィールドの変更
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】このコンパイルユニットは名前付きモジュールに関連しているため、名前付きパッケージeclipseを宣言する必要があります。
-
[解決済み】imageio.IIOException: 入力ファイルが読み込めない
-
[解決済み】javaで指定されたファイルが見つからない
-
[解決済み】エラー。Selection does not contain a main type
-
[解決済み】デフォルトのキーストアファイルが存在しない?
-
[解決済み】Javaを使用するSelenium - ドライバの実行ファイルのパスは、webdriver.gecko.driverシステムプロパティで設定する必要があります。
-
[解決済み】Java Error "Exception in thread "main" java.util.InputMismatchException" Array プログラムで発生。
-
[解決済み】Java LinkedListでNodesを使用する
-
[解決済み】Java: GZIPInputStreamの作成に失敗しました。GZIP形式ではありません
-
[解決済み] プライベートメソッドを呼び出す方法はありますか?