我看到了一个朋友发给我的片段。它有一个非常奇怪的行为。我尝试谷歌代码,看看我是否在互联网上找到了什么,但没有运气。我无法联系我的朋友,所以我对它在做什么感到愤怒。
public class Test {
public static void main(String[] args) throws MalformedURLException {
System.out.println(Boolean.TRUE); //This prints false
}
static {
try {
Field value = Boolean.class.getDeclaredField("value");
value.setAccessible(true);
value.set(Boolean.TRUE, value.get(Boolean.FALSE));
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
我认为,就像那段代码一样,它被声明为静态,它将首先运行main
方法,并在该静态代码内部更改所有Boolean
实例的值(?我不知道,我需要专家意见来确认这一点。
Field value = Boolean.class.getDeclaredField("value");
value.setAccessible(true);
value.set(Boolean.TRUE, value.get(Boolean.FALSE));
槽反射将Boolean.TRUE
的常量值设置为 Boolean.FALSE
。那是。。完全按照您在代码中读取的内容。
static
初始值设定项块是在 main
方法之前执行的,请不要让顺序欺骗您,让您认为它会在以后发生。
引用这篇文章:
假设没有 SecurityManager 阻止您这样做,您可以使用 setAccessible 绕过私有并重置修饰符以摆脱 final,并实际修改私有静态 final 字段。
这是因为执行顺序保证了静态初始化块将在类实例的其他初始化之前执行。 静态初始化是在加载类时完成的; 通常在类的第一个引用处。
当静态块在调用 main
方法之前更改 Boolean.TRUE
的值时,它会打印更改的值。
请考虑以下示例(源):
/*
* Here we will learn to see how the different part (Ananymous Block, Constructor and Static Block ) of class will behave
* and what would be the order of execution.
*/
class JBTCLass {
/*
* Here Creating the Ananymous Block
*/
{
System.out.println("Inside Ananymous Block");
}
/*
* Now Creating the Static Block in Class
*/
static {
System.out.println("Inside Static Block");
}
/*
* Here Creating the Constructor of Class
*/
JBTCLass() {
System.out.println("Inside Constructor of Class");
}
public static void main(String[] args) {
// Creating the Object of the Class
JBTCLass obj = new JBTCLass();
System.out.println("*******************");
// Again Creating Object of Class
JBTCLass obj1 = new JBTCLass();
}
}
结果:
Inside Static Block
Inside Ananymous Block
Inside COnstructor of Class
*******************
Inside Ananymous Block
Inside COnstructor of Class
public static final Boolean TRUE = new Boolean(true);
常量 TRUE 是对象的参考点,final 表示您无法将其更改为指向另一个对象。由于您已将value
常量更改为 false,因此现在对象值为 false。