の力について学べば学ぶほど、java.lang.reflect.AccessibleObject.setAccessible
それが何をすることができるかに驚いています。これは私の質問への私の回答から転用されています(リフレクションを使用して、単体テストの静的な最終File.separatorCharを変更します)。
import java.lang.reflect.*;
public class EverythingIsTrue {
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}
}
あなたは本当にとんでもないことをすることができます:
public class UltimateAnswerToEverything {
static Integer[] ultimateAnswer() {
Integer[] ret = new Integer[256];
java.util.Arrays.fill(ret, 42);
return ret;
}
public static void main(String args[]) throws Exception {
EverythingIsTrue.setFinalStatic(
Class.forName("java.lang.Integer$IntegerCache")
.getDeclaredField("cache"),
ultimateAnswer()
);
System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42"
}
}
おそらく、API設計者は乱用setAccessible
可能であることを理解していますが、それを提供するための正当な使用法があることを認めたに違いありません。だから私の質問は:
- 本当に正当な用途は
setAccessible
何ですか?- Javaは、そもそもこの必要性がないように設計されているのでしょうか?
- そのような設計の負の結果(もしあれば)は何でしょうか?
setAccessible
正当な使用のみに制限できますか?- それだけ
SecurityManager
ですか?- それはどのように機能しますか?ホワイトリスト/ブラックリスト、粒度など?
- アプリケーションで構成する必要があるのは一般的ですか?
- 構成に
setAccessible
関係なくクラスを証明できるようにクラスを作成できSecurityManager
ますか?- それとも、構成を管理する人のなすがままになっていますか?
- それだけ
私はもう1つの重要な質問だと思います:これについて心配する必要がありますか???
私のクラスのどれも、強制力のあるプライバシーのいかなる類似もまったくありません。シングルトンパターン(そのメリットについて疑問を投げかける)を実施することは現在不可能です。上記の私のスニペットが示すように、Javaの基本的な動作の基本的な仮定でさえ、保証されているとは言えません。
これらの問題は本当ではありませんか???
さて、私は確認しました:のおかげでsetAccessible
、Java文字列は不変ではありません。
import java.lang.reflect.*;
public class MutableStrings {
static void mutate(String s) throws Exception {
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set(s, s.toUpperCase().toCharArray());
}
public static void main(String args[]) throws Exception {
final String s = "Hello world!";
System.out.println(s); // "Hello world!"
mutate(s);
System.out.println(s); // "HELLO WORLD!"
}
}
これが大きな懸念であると考えるのは私だけですか?