当我使用this关键字访问类中的非静态变量时,Java不会给出任何错误.但是当我不使用它时,Java会出错.我为什么要用this?
我知道通常应该什么时候使用this,但这个例子与正常用法非常不同.
例:
class Foo {
// int a = b; // gives error. why ?
int a = this.b; // no error. why ?
int b;
int c = b;
int var1 = this.var2; // very interesting
int var2 = this.var1; // very interesting
}
Run Code Online (Sandbox Code Playgroud) 以下内容无法编译,给出"非法转发引用"消息:
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呢?
分析以下静态块中的一些奇怪场景:
static {
System.out.println("Inside Static Block");
i=100; // Compilation Successful , why ?
System.out.println(i); // Compilation error "Cannot reference a field before it is defined"
}
private static int i=100;
Run Code Online (Sandbox Code Playgroud)
使用时,相同的代码工作正常:
static {
System.out.println("Inside Static Block");
i=100; // Compilation Successful , why ?
System.out.println(MyClass.i); // Compiles OK
}
private static int i=100;
Run Code Online (Sandbox Code Playgroud)
不确定为什么变量初始化在SOP需要时不需要使用类名进行变量访问?
在研究另一个问题时,我惊讶地发现以下Java代码编译时没有错误:
public class Clazz {
int var = this.var + 1;
}
Run Code Online (Sandbox Code Playgroud)
在我的JDK6中,var初始化为1.
上面的代码是否具有明确定义的语义,或者它的行为是否未定义?如果您说它定义明确,请引用JLS的相关部分.
直观地说,在Java中,实例变量初始化器按它们在类声明中出现的顺序执行.
这肯定是我正在使用的JDK中的情况.例如,以下内容:
public class Clazz {
int x = 42;
int y = this.z;
int z = this.x;
void print() {
System.out.printf("%d %d %d\n", x, y, z);
}
public static void main(String[] args) {
new Clazz().print();
}
}
Run Code Online (Sandbox Code Playgroud)
打印42 0 42(换句话说,y选择默认值z).
这个订单真的有保证吗?我一直在查看JLS,但找不到任何明确的确认.