当前位置:编程学习 > JAVA >>

一个关于java静态初始化的奇怪问题

代码如下

public class Test {
static {
x = 5;
//System.out.println("x:" + x); //Cannot reference a field before it is defined
}
static int x, y;

public static void main(String[] args) {
x--;
myMethod();
System.out.println(x + y++ + x);
}

public static void myMethod() {
y = (x++) + (++x);
}
}


问题在于第四行注释掉的代码,为什么会报错,上面向x=5引用没错,打印语句就报Cannot reference a field before it is defined 错误 说x没有定义,可是x=5的赋值语句怎么没有报这个错呢 Java 初始化 --------------------编程问答-------------------- 是挺好玩的,然后我把static int x, y;放到最上面,就不会报错了。
推测,x=5这种赋值语句会全局搜索是否有此定义的属性,而静态块里的直接使用操作,只会查找内存是否已加载次属性。 --------------------编程问答--------------------

    static int x, y;
    static {
        x = 5;
        //System.out.println("x:" + x); //Cannot reference a field before it is defined
    }
--------------------编程问答-------------------- 我也不明白,求解 --------------------编程问答-------------------- 静态属性和静态代码块是按顺序加载的,所以是那个写在上面的那个先加载 --------------------编程问答-------------------- 应该是按顺序加载的吧 --------------------编程问答-------------------- http://bbs.csdn.net/topics/390122816
LZ可以参考上面的链接,其实这跟JVM的加载无关,这是编译器的规范,就像C里面需要先声明才能使用的意思是一样的。 --------------------编程问答-------------------- 还是没人能解答吗。好奇乖的问题 --------------------编程问答--------------------
引用 2 楼 ghostkngiht 的回复:

    static int x, y;
    static {
        x = 5;
        //System.out.println("x:" + x); //Cannot reference a field before it is defined
    }


引用 2 楼 ghostkngiht 的回复:

    static int x, y;
    static {
        x = 5;
        //System.out.println("x:" + x); //Cannot reference a field before it is defined
    }

语法怎么写我知道 我只是想知道为什么注释掉那一行报错而上一行不报错 --------------------编程问答-------------------- 我认为是这样的,程序编译是按照顺序来编译的,没有先定义x,就使用它才会报错,静态代码块和静态成员变量和类一起加载,也就是类创建时他们也就生成了,所以应该在使用前先定义 --------------------编程问答-------------------- 这问题在本论坛已经见过很多次了 --------------------编程问答--------------------
引用 楼主 hebutscs 的回复:
代码如下

public class Test {
static {
x = 5;
//System.out.println("x:" + x); //Cannot reference a field before it is defined
}
static int x, y;

public static void main(String[] args) {
x--;
myMethod();
System.out.println(x + y++ + x);
}

public static void myMethod() {
y = (x++) + (++x);
}
}


问题在于第四行注释掉的代码,为什么会报错,上面向x=5引用没错,打印语句就报Cannot reference a field before it is defined 错误 说x没有定义,可是x=5的赋值语句怎么没有报这个错呢


是因为加载顺序,java的加载顺序是 1.加载静态成员/代码块  2.加载非静态成员/代码块 3.调用构造方法
没运行时会检查有没有第四行x这个变量,发现在第六行有定义就没报错,
而加载时,加载静态代码块(第二行)和静态成员(第六行)是按顺序加载的,先加载第二行的代码块发现没有定义变量(第六行还没加载),所以报错了
而当你把定义放到前面时就先加载变量的定义了,所以没报错 --------------------编程问答--------------------
引用 8 楼 hebutscs 的回复:
Quote: 引用 2 楼 ghostkngiht 的回复:


    static int x, y;
    static {
        x = 5;
        //System.out.println("x:" + x); //Cannot reference a field before it is defined
    }


引用 2 楼 ghostkngiht 的回复:

    static int x, y;
    static {
        x = 5;
        //System.out.println("x:" + x); //Cannot reference a field before it is defined
    }

语法怎么写我知道 我只是想知道为什么注释掉那一行报错而上一行不报错


在定义之前引用了不能引用 --------------------编程问答-------------------- 在类中 静态优先于非静态初始化
所以 你的声明在后边吧 --------------------编程问答-------------------- 编译原理的问题吧
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,