我正在研究一个问题来存储两个类的引用
例如:
class A {
B b;
A(B b){
this.b = b;}
}
class B {
A a;
B(A a){
this.a = a;}
}
public static void main(String...s){
A a = new A(new B(null));
a.b.a = a;
}
现在,如果我使用下面的语句而不是上面的初始化:
A a = new A(new B(a));
我得到以下错误,这是非常明显的:
Main.java:19: error: variable a might not have been initialised
A a = new A(new B(a));
但如果我在 JShell 上尝试同样的操作,它工作得很好(只是为了额外确保variable a
从未初始化过,我检查过variable a
在执行确认之前未初始化的语句之前:
可能我在这里遗漏了一些东西,但是有人可以帮助我理解为什么在 JAVA 中执行同一条语句有两种不同的行为吗?
理解这个问题的一个简单方法是允许以下语句Jshell
但在正常程序中则不然:
var somevar = somevar;
该声明A a = new A(new B(a));
is not局部变量的声明。
但首先,您描述的问题可以简化为:
jshell> int a = a;
a ==> 0
那么,效果如何呢?
以及Snippets http://openjdk.java.net/jeps/222#SnippetsJEP 222 说:
在 JShell 中,“变量”是一个存储位置并具有关联的类型。变量是显式创建的字段声明片段:
int a = 42;
或通过表达式隐式(见下文)。变量有少量字段语义/语法(例如,volatile
允许修改)。但是,变量没有包含它们的用户可见类,并且通常会像这样查看和使用局部变量.
因此,它们的行为有点像字段,也有点像局部变量。
与字段类似,但与局部变量不同,没有初始化程序的声明将分配一个默认值,例如
jshell> int b;
b ==> 0
但是,回到int a = a;
。部分State http://openjdk.java.net/jeps/222#StateJEP 222 说:
JShell 状态保存在 JShell 实例中。在 JShell 中使用以下命令评估代码片段eval(...)
方法、产生错误、声明代码或执行语句或表达式。对于带有初始值设定项的变量,声明和执行都发生.
因此,变量的声明和初始化器的执行是两个独立的操作。
这意味着当执行初始化程序时,变量已经被声明,并且已经被分配了默认值。
有效,int a = a;
被评估为:
jshell> int a;
a ==> 0
jshell> a = a;
a ==> 0
这就是 jshell REPL 的设计工作原理。这不是一个错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)