Java中静态和非静态正向引用的内部工作
我正在使用Java中的前向引用,我想知道为什么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;
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”引用,将发生的内部过程。当使用这两种方法时会发生什么,以及为什么我们能够达到与“阅读前声明”规则相矛盾的情况(在某种程度上)。