Mar*_*tin 53 java static instance forward
以下内容无法编译,给出"非法转发引用"消息:
class StaticInitialisation {
static
{
System.out.println("Test string is: " + testString);
}
private static String testString;
public static void main(String args[]) {
new StaticInitialisation();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,以下编译:
class InstanceInitialisation1 {
{
System.out.println("Test string is: " + this.testString);
}
private String testString;
public static void main(String args[]) {
new InstanceInitialisation1();
}
}
Run Code Online (Sandbox Code Playgroud)
但以下内容无法编译,给出"非法转发引用"消息:
class InstanceInitialisation2 {
private String testString1;
{
testString1 = testString2;
}
private String testString2;
public static void main(String args[]) {
new InstanceInitialisation2();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么StaticInitialisation和InstanceInitialisation2不能编译,而InstanceInitialisation1呢?
Jon*_*eet 57
这由JLS 第8.3.3节涵盖:
使用声明在使用后以文本形式出现的类变量有时会受到限制,即使这些类变量在范围内(第6.3节).具体来说,如果满足以下所有条件,则为编译时错误:
在使用类变量之后,类或接口C中的类变量声明以文本形式出现;
在C的类变量初始化程序或C的静态初始化程序中使用是一个简单的名称;
使用不在作业的左侧;
C是封闭使用的最内层类或接口.
使用在使用后以声明方式显示声明的实例变量有时会受到限制,即使这些实例变量在范围内也是如此.具体来说,如果满足以下所有条件,则为编译时错误:
在使用实例变量之后,类或接口C中的实例变量的声明以文本形式出现;
在C的实例变量初始值设定项或C的实例初始值设定项中使用是一个简单的名称;
使用不在作业的左侧;
C是封闭使用的最内层类或接口.
在你的第二种情况下,使用不是一个简单的名称 - 你this明确地说.这意味着它不符合上面引用的第二个列表中的第二个项目符号,因此没有错误.
如果您将其更改为:
System.out.println("Test string is: " + testString);
Run Code Online (Sandbox Code Playgroud)
...然后它将无法编译.
或者在相反的方向,您可以将静态初始化程序块中的代码更改为:
System.out.println("Test string is: " + StaticInitialisation.testString);
Run Code Online (Sandbox Code Playgroud)
奇怪,但这就是它的方式.