Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中静态和非静态正向引用的内部工作_Java_Static_Non Static_Forward Reference - Fatal编程技术网

Java中静态和非静态正向引用的内部工作

Java中静态和非静态正向引用的内部工作,java,static,non-static,forward-reference,Java,Static,Non Static,Forward Reference,我正在使用Java中的前向引用,我想知道为什么Java允许使用ClassName(在静态变量中)或this引用(在实例变量中)进行前向引用?在JVM级别发生的后台进程是什么?例如: 静态正向参考- class StaticForwardReferences { static { sf1 = 10; // (1) int b = sf1 = 20; // (2) int c = StaticForwardReferences.sf1;

我正在使用Java中的前向引用,我想知道为什么Java允许使用
ClassName
(在静态变量中)或
this
引用(在实例变量中)进行前向引用?在JVM级别发生的后台进程是什么?例如:

静态正向参考-

class StaticForwardReferences {
    static {
        sf1 = 10;   // (1)
        int b = sf1 = 20;   // (2)
        int c = StaticForwardReferences.sf1; // (3) Works fine
        // Above statement allows the allocation of value of 'sf1'
        // to variable 'c' just because it is accessed with class name
        // instead of direct name

        // whereas below statement throws illegal forward reference
        // error at compile time
        System.out.println(sf1); // (4) Illegal forward reference
    }
    static int sf1 = sf2 = 30;
    static int sf2;

    public static void main(String[] args) {}
}
class NonStaticForwardReferences {
    {
        nsf1 = 10;
        System.out.println(this.nsf1);  // 10
        nsf1 = sf1;
        // System.out.println(nsf1); Illegal forward reference
        int b = nsf1 = 20;

        int c = this.nsf1;
        System.out.println(c);  // 20
        // why variable 'c' is initialized to 20 when used with 'this' reference
        // instead of showing illegal forward reference, how it works in the background?
   }

   int nsf1 = nsf2 = 30;
   int nsf2;
   static int sf1 = 5;

   public static void main(String[] args) {}
}
是否存在任何类型的临时存储,当我们通过在上述(1)和(2)步骤中声明变量之前分配变量来进行正向引用时,在其中存储值,如果我们打印变量
c
的值,它将显示最近分配给
sf1
的值

非静态正向参考-

class StaticForwardReferences {
    static {
        sf1 = 10;   // (1)
        int b = sf1 = 20;   // (2)
        int c = StaticForwardReferences.sf1; // (3) Works fine
        // Above statement allows the allocation of value of 'sf1'
        // to variable 'c' just because it is accessed with class name
        // instead of direct name

        // whereas below statement throws illegal forward reference
        // error at compile time
        System.out.println(sf1); // (4) Illegal forward reference
    }
    static int sf1 = sf2 = 30;
    static int sf2;

    public static void main(String[] args) {}
}
class NonStaticForwardReferences {
    {
        nsf1 = 10;
        System.out.println(this.nsf1);  // 10
        nsf1 = sf1;
        // System.out.println(nsf1); Illegal forward reference
        int b = nsf1 = 20;

        int c = this.nsf1;
        System.out.println(c);  // 20
        // why variable 'c' is initialized to 20 when used with 'this' reference
        // instead of showing illegal forward reference, how it works in the background?
   }

   int nsf1 = nsf2 = 30;
   int nsf2;
   static int sf1 = 5;

   public static void main(String[] args) {}
}
请对上述两起案件幕后发生的背景过程进行说明。提前感谢!:)

说明了将前向引用静态变量(“类变量”)作为编译器错误的条件,尽管它没有说明推理

有时,即使这些类变量在范围内(§6.3),但其声明在使用后以文本形式出现的类变量的使用受到限制。具体而言,如果以下所有条件均为真,则为编译时错误:

  • 类或接口C中的类变量声明在使用类变量后以文本形式出现

  • 在C的类变量初始值设定项或C的静态初始值设定项中使用一个简单的名称

  • 使用不在作业的左侧

  • C是包含该用法的最内层类或接口

(斜体强调矿井)

实例变量正向引用错误出现时出现类似情况:

即使这些实例变量在作用域中,但在使用后以文本形式显示其声明的实例变量的使用有时会受到限制。具体而言,如果以下所有条件均为真,则为编译时错误:

  • 类或接口C中实例变量的声明在使用实例变量后以文本形式出现

  • 在C的实例变量初始值设定项或C的实例初始值设定项中使用一个简单的名称

  • 使用不在作业的左侧

  • C是包含该用法的最内层类或接口

(斜体强调矿井)


在这两种情况下,使用简单的名称是这里的关键条件。这意味着在不使用任何限定符(如
this
或类名)的情况下使用变量。这就是为什么
This.nsf1
NonStaticForwardReferences
中工作。如果删除此,则会发生错误。这也是为什么
sf1
出现错误和
StaticForwardReferences.sf1没有错误。

Java要求在任何初始值设定项中使用字段之前必须先声明字段 表达式,如果该字段用于初始值设定项中赋值的右侧 表情。这本质上意味着字段的声明必须在 字段的值在初始值设定项表达式中读取

使用简单名称进行正向引用时,静态初始值设定项块中的代码是 同样以上述阅读前声明规则为准

与实例初始值设定项表达式一样,关键字“this”和“super”可用于
引用实例初始值设定项块中的当前对象。

禁止正向引用并不意味着在初始化时创建变量。“后台过程”就是在给定(静态)变量的情况下,同时分配类和对象。(也就是说“零”:实际上,它可能是用
calloc
memset
实现的。)


正向引用规则是为了防止看到这些第一个值,特别是对于假定只有一个值的
final
变量。但它们的存在是为了捕捉人为错误,而且它们本身并不完美:只有对于常量变量,初始化才会发生,而默认值是不可观察的。明确指定
或类名是演示此效果的最简单方法。

我感谢您的回答,但这不是我想要的。我知道Java中静态和非静态情况下的前向引用规则,但我问的是,如果我使用类名或“this”引用,将发生的内部过程。当使用这两种方法时会发生什么,以及为什么我们能够达到与“阅读前声明”规则相抵触的情况(在某种程度上)。原因是这是一种安全措施,并不试图涵盖所有情况。我感谢你的回答,但这不是我要求的。我知道Java中静态和非静态情况下的前向引用规则,但我问的是,如果我使用类名或“this”引用,将发生的内部过程。当使用这两种方法时会发生什么,以及为什么我们能够达到与“阅读前声明”规则相矛盾的情况(在某种程度上)。