我对的力量了解得越多,我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配置如何,我都可以将自己的类写成-proof 吗?
还是由谁来管理配置?
我猜一个更重要的问题是:我需要为此担心吗???
我的课程都没有任何类似的可执行隐私。现在无法执行单例模式(不考虑其优缺点)。正如我上面的摘录所示,甚至几乎无法保证有关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());
}
我是唯一认为这是一个巨大问题的人吗?
SMILET
慕的地10843