2

我偶然发现了一位朋友发给我的一个片段。它有一个非常奇怪的行为。我尝试用谷歌搜索代码,看看我是否在互联网上找到了一些东西,但没有运气。我无法联系到我的朋友,所以我很好奇它在做什么。

    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实例的值(?)。我不知道,我需要专家意见来证实这一点。

4

3 回答 3

4
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 绕过 private 并重置修饰符以摆脱 final,并实际修改私有静态 final 字段。

于 2013-10-15T01:33:14.533 回答
2

这是因为执行顺序保证了静态初始化块将在类实例的其他初始化之前执行。加载类时进行静态初始化;通常在类的第一个参考。

由于静态块在调用方法Boolean.TRUE之前更改了 的值,因此它会打印更改的值。main

考虑以下示例(source):

/*
 * 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
于 2013-10-15T01:40:48.550 回答
1
public static final Boolean TRUE = new Boolean(true);

常量 TRUE 是一个对象的引用点,final 意味着您不能将其更改为指向另一个对象。由于您已将value常量更改为 false,所以现在对象值为 false。

于 2013-10-15T02:01:00.140 回答