谁能解释这段与 Java 中的阴影相关的代码?
Can anyone explain this code related to shadowing in Java?
在阅读有关嵌套的 Oracle 文档时 类,我发现这段代码的输出我无法理解。有人可以解释一下吗?
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
下面是这个例子的输出:
x = 23
this.x = 1
ShadowTest.this.x = 0 //why is 0 printed here? why not 1 because "this" is the object of FirstLevel class.
可以找到原代码here
局部变量x
隐藏了this.x
和ShadowTest.this.x
。
内部class(this.x
)的实例变量隐藏了封闭class(可以被ShadowTest.this.x
访问)的实例变量。
System.out.println("x = " + x); // prints the local variable passed to the method
System.out.println("this.x = " + this.x); // prints the instance variable of the inner class
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); // prints the instance variable of the enclosing class instance
我觉得除了找到的文档之外还没有完全解释 here 所以我将根据我最近的理解尝试更详细地解释。
我已将 ShadowClass
外部 class 的名称更改为 NestedClasses
并将变量从类型 int
更改为类型 String
。
这是在第一个嵌套 class 中添加第二个嵌套 class 的示例,以显示 NestedClasses.this.x
如何继续在 classes 的更深层表现。
public class NestedClasses {
public String x = "outer class variable";
class FirstLevel {
public String x = "first level class variable";
void methodInFirstLevel(String x) {
System.out.println("methodInFirstLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
}
class SecondLevel {
public String x = "second level class variable";
void methodInSecondLevel(String x) {
System.out.println("methodInSecondLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
System.out.println("FirstLevel.this.x = " + FirstLevel.this.x);
System.out.println("NestedClasses.FirstLevel.this.x = " + NestedClasses.FirstLevel.this.x);
}
}
}
public static void main(String[] args) {
NestedClasses st = new NestedClasses();
NestedClasses.FirstLevel fl = st.new FirstLevel();
NestedClasses.FirstLevel.SecondLevel sl = fl.new SecondLevel();
fl.methodInFirstLevel("first level method arg");
System.out.println();
sl.methodInSecondLevel("second level method arg");
}
}
输出:
methodInFirstLevel:
x
= 第一级方法 arg
this.x
= 第一级 class 变量
NestedClasses.this.x
= 外部 class 变量
SecondLevel 方法:
x
= 二级方法 arg
this.x
=二级class变量
NestedClasses.this.x
= 外部 class 变量
FirstLevel.this.x
=一级class变量
NestedClasses.FirstLevel.this.x
=一级class变量
三个实例化对象(st
、fl
、sl
)中的每一个都包含指向不同内存的指针space 在可以找到 x
的值的堆中。我相信编译器正在向最外层“向后”搜索以找到第一个匹配的 class,当它看到嵌套 class 中的 class 名称前缀为 this
时。它找到的第一个匹配 class 是它在确定需要搜索哪个对象实例以找到 x
时将引用的 class。这意味着 NestedClasses.FirstLevel.this.x
实际上是向后退两步,向前退一步以确定在堆中查看哪个 内存 space,即哪个内存 space x
参考.
夏天:
NestedClasses.this.x
- 带前缀的 Class 名称
NestedClasses
告诉 JVM 正在使用哪个 class,这个 class 必须可以从当前范围访问。
-
this
关键字告诉 JVM 查看 内存 space 被引用的 class 的实例化对象,而不是 class 对象本身的 内存 space(用于 class 的静态成员)。更具体地说,this
将引用用于(和需要)实例化非静态内部 class. 的外部 class 的实例化
- 附加到
this
的对象成员 x
告诉 JVM 在它正在查看的 内存 space 中搜索什么。
在阅读有关嵌套的 Oracle 文档时 类,我发现这段代码的输出我无法理解。有人可以解释一下吗?
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
下面是这个例子的输出:
x = 23
this.x = 1
ShadowTest.this.x = 0 //why is 0 printed here? why not 1 because "this" is the object of FirstLevel class.
可以找到原代码here
局部变量x
隐藏了this.x
和ShadowTest.this.x
。
内部class(this.x
)的实例变量隐藏了封闭class(可以被ShadowTest.this.x
访问)的实例变量。
System.out.println("x = " + x); // prints the local variable passed to the method
System.out.println("this.x = " + this.x); // prints the instance variable of the inner class
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); // prints the instance variable of the enclosing class instance
我觉得除了找到的文档之外还没有完全解释 here 所以我将根据我最近的理解尝试更详细地解释。
我已将 ShadowClass
外部 class 的名称更改为 NestedClasses
并将变量从类型 int
更改为类型 String
。
这是在第一个嵌套 class 中添加第二个嵌套 class 的示例,以显示 NestedClasses.this.x
如何继续在 classes 的更深层表现。
public class NestedClasses {
public String x = "outer class variable";
class FirstLevel {
public String x = "first level class variable";
void methodInFirstLevel(String x) {
System.out.println("methodInFirstLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
}
class SecondLevel {
public String x = "second level class variable";
void methodInSecondLevel(String x) {
System.out.println("methodInSecondLevel:");
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("NestedClasses.this.x = " + NestedClasses.this.x);
System.out.println("FirstLevel.this.x = " + FirstLevel.this.x);
System.out.println("NestedClasses.FirstLevel.this.x = " + NestedClasses.FirstLevel.this.x);
}
}
}
public static void main(String[] args) {
NestedClasses st = new NestedClasses();
NestedClasses.FirstLevel fl = st.new FirstLevel();
NestedClasses.FirstLevel.SecondLevel sl = fl.new SecondLevel();
fl.methodInFirstLevel("first level method arg");
System.out.println();
sl.methodInSecondLevel("second level method arg");
}
}
输出:
methodInFirstLevel:
x
= 第一级方法 arg
this.x
= 第一级 class 变量
NestedClasses.this.x
= 外部 class 变量
SecondLevel 方法:
x
= 二级方法 arg
this.x
=二级class变量
NestedClasses.this.x
= 外部 class 变量
FirstLevel.this.x
=一级class变量NestedClasses.FirstLevel.this.x
=一级class变量
三个实例化对象(st
、fl
、sl
)中的每一个都包含指向不同内存的指针space 在可以找到 x
的值的堆中。我相信编译器正在向最外层“向后”搜索以找到第一个匹配的 class,当它看到嵌套 class 中的 class 名称前缀为 this
时。它找到的第一个匹配 class 是它在确定需要搜索哪个对象实例以找到 x
时将引用的 class。这意味着 NestedClasses.FirstLevel.this.x
实际上是向后退两步,向前退一步以确定在堆中查看哪个 内存 space,即哪个内存 space x
参考.
夏天:
NestedClasses.this.x
- 带前缀的 Class 名称
NestedClasses
告诉 JVM 正在使用哪个 class,这个 class 必须可以从当前范围访问。 -
this
关键字告诉 JVM 查看 内存 space 被引用的 class 的实例化对象,而不是 class 对象本身的 内存 space(用于 class 的静态成员)。更具体地说,this
将引用用于(和需要)实例化非静态内部 class. 的外部 class 的实例化
- 附加到
this
的对象成员x
告诉 JVM 在它正在查看的 内存 space 中搜索什么。