Java 静态变负荷过程

Java 静态变负荷过程,java,compiler-errors,jvm,vm-implementation,Java,Compiler Errors,Jvm,Vm Implementation,最近,我研究了虚拟机如何加载静态变量,但遇到了如下问题: public class Example{ static{ num = 3; System.out.print(num); } public static int num; } 编译器报告一个错误。我认为num有内存区域和值。为什么我不能访问num变量?static块和声明是按编码顺序执行的。这意味着在执行静态块时,num字段尚未定义 简单的修复方法是将声明移到块上方 (除其他外

最近,我研究了虚拟机如何加载静态变量,但遇到了如下问题:

public class Example{

    static{
        num = 3;
        System.out.print(num);
    }
    public static int num;
}

编译器报告一个错误。我认为
num
有内存区域和值。为什么我不能访问
num
变量?

static
块和声明是按编码顺序执行的。这意味着在执行静态块时,
num
字段尚未定义

简单的修复方法是将声明移到块上方

(除其他外)说明变量在声明之前可以赋值,但在声明变量之前不能访问变量的值,除非其名称是完全限定的,因此编译:

public class Example {
    static{
        num = 3; // assignment OK without qualifying the name
        System.out.print(Example.num); // name must be qualified to access value
    }
    public static int num;
}

更有趣的是,如果在声明变量之前访问了该变量,则会使用其默认值,并且声明时仍会进行初始化,因此以下代码:

public class Example {
    static{
        System.out.println(Example.num); // uses default value
        num = 3;                         // assignment OK
        System.out.println(Example.num); // assigned value (3) is visible
    }

    public static int num = 1;           // initialization to 1 occurs

    static{
        System.out.print(Example.num);   // initialized value (1) is visible 
    }
}
生成此输出:

0
3
1

静态
块和声明按编码顺序执行。这意味着在执行静态块时,
num
字段尚未定义

简单的修复方法是将声明移到块上方

(除其他外)说明变量在声明之前可以赋值,但在声明变量之前不能访问变量的值,除非其名称是完全限定的,因此编译:

public class Example {
    static{
        num = 3; // assignment OK without qualifying the name
        System.out.print(Example.num); // name must be qualified to access value
    }
    public static int num;
}

更有趣的是,如果在声明变量之前访问了该变量,则会使用其默认值,并且声明时仍会进行初始化,因此以下代码:

public class Example {
    static{
        System.out.println(Example.num); // uses default value
        num = 3;                         // assignment OK
        System.out.println(Example.num); // assigned value (3) is visible
    }

    public static int num = 1;           // initialization to 1 occurs

    static{
        System.out.print(Example.num);   // initialized value (1) is visible 
    }
}
生成此输出:

0
3
1

Put
public static int num位于块上方(在定义字段之前不能引用该字段)。我不知道这是否是输入错误,但您忘记编写
int
-1,因为您的代码未编译,但您声明了一个运行时错误,并且不知道是哪个错误。始终复制/粘贴错误和异常输出。放置
公共静态int-num位于块上方(在定义字段之前不能引用该字段)。我不知道这是不是打字错误,但是你忘了写
int
-1,因为你的代码没有编译,但是你声明了一个运行时错误,不要告诉哪一个。总是复制/粘贴错误和异常输出。我读了关于虚拟机如何加载类进程的文章。我认为类文件中的num的符号引用已经加载到虚拟机中,所以num变量已经声明。我是否误解了?酷,我理解你的解释!但是你能解释一下为什么我可以使用完全限定的静态变量来访问它吗?非常感谢。@KrystalJake它是在语言规范中定义的(一个“解释”),原因是我可以冒险猜测,因为字段在技术上没有定义,限定允许编译器为实际字段创建准确的占位符。我阅读了有关虚拟机加载类过程的文章。我认为类文件中的num符号引用已加载到虚拟机中,因此声明了num变量。我是否误解了?酷,我理解您的解释!但是你能解释一下为什么我可以使用完全限定的静态变量来访问它吗?非常感谢。@KrystalJake它是在语言规范中定义的(一个“解释”),原因是我可以冒险猜测,因为字段在技术上没有定义,限定允许编译器为实际字段创建准确的占位符