匿名Thread类无法访问非静态实例变量的问题咨询
关于匿名Thread类访问外部实例变量的问题解答
这个问题其实是静态上下文作用域和匿名类中this的指向这两个知识点的交叉坑,咱们掰开揉碎了说:
为什么会报错?
你写的main方法是静态方法,属于静态上下文——静态上下文里没有当前类(AnonymousThreadDemo)的对象实例,而非静态变量num是属于对象的,不是属于类的。所以不管你用不用匿名类,在静态方法里直接访问num本身就是不允许的,编译器提示你把num设为静态,是因为静态变量属于类,能在静态上下文中直接访问,但这只是临时解决方案,未必符合你的代码设计初衷。
匿名类里的this到底指谁?
你疑惑“匿名类能用this为啥不能访问非静态变量”,核心是搞混了this的指向:这里的匿名类是Thread的子类实例,所以你在匿名类里写的this,指代的是这个新创建的Thread对象,不是外部类AnonymousThreadDemo的对象!
如果想访问外部类的实例变量,你需要用外部类类名.this.变量名的语法,但有个前提:你得在非静态上下文里创建这个匿名类(也就是在外部类的非静态方法里),因为非静态上下文才有外部类的实例。
修正代码的两种思路
思路1:在静态main里先创建外部类实例,通过实例访问
public class AnonymousThreadDemo { int num; public AnonymousThreadDemo(int num) { this.num = num; } public static void main(String[] args) { // 先实例化外部类,拿到对象引用 AnonymousThreadDemo demo = new AnonymousThreadDemo(20); Thread thread = new Thread() { @Override public void run() { // 通过外部类对象引用访问num System.out.println("当前num值:" + demo.num); } }; thread.start(); } }
思路2:把匿名Thread的创建放到非静态方法里
这样就能直接用AnonymousThreadDemo.this来访问外部类的实例变量:
public class AnonymousThreadDemo { int num; public AnonymousThreadDemo(int num) { this.num = num; } // 非静态方法,自带外部类实例的上下文 public void startMyThread() { Thread thread = new Thread() { @Override public void run() { // 用外部类类名.this明确指向外部类实例的num System.out.println("当前num值:" + AnonymousThreadDemo.this.num); // 如果匿名类里没有同名变量,直接写num也可以,编译器会自动找外部类的成员 } }; thread.start(); } public static void main(String[] args) { AnonymousThreadDemo demo = new AnonymousThreadDemo(20); demo.startMyThread(); } }
最后总结一下
- 静态上下文(静态方法、静态块)不能直接访问非静态成员,必须通过类的实例来操作;
- 匿名类的
this只指代匿名类自己的对象,要访问外部类成员得加类名限定; - 把变量设为静态只是权宜之计,如果
num是每个对象独有的属性,不要随便改成静态,不然会导致多个对象共享同一个num值,引发逻辑bug。
内容的提问来源于stack exchange,提问作者Nishant_Singh
相关产品推荐
相关产品推荐

