任何人都可以解释为什么这段代码返回false

时间:2013-10-15 01:29:58

标签: java semantics

我遇到了一个朋友寄给我的片段。它有一个非常奇怪的行为。我尝试谷歌代码,看看我是否在互联网上发现了一些东西,但没有运气。我无法联系到我的朋友,所以我对它正在做的事情很了不起。

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

3 个答案:

答案 0 :(得分:4)

Field value = Boolean.class.getDeclaredField("value");
value.setAccessible(true);
value.set(Boolean.TRUE, value.get(Boolean.FALSE));

通过反射,Boolean.TRUE的常量值设置为Boolean.FALSE。那就是..正如你可以在代码中看到的那样。

static初始化程序块在main方法之前执行,不要让订单欺骗您以为它会在以后发生。

引自this帖子:

  

假设没有SecurityManager阻止你这样做,你可以使用setAccessible绕过private并重置修饰符以摆脱final,并实际修改私有静态final字段。

答案 1 :(得分: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

答案 2 :(得分:1)

public static final Boolean TRUE = new Boolean(true);

常量TRUE是对象的参考点,final表示您无法将其更改为指向另一个对象。由于您已将value常量更改为false,因此现在对象值为false。