Java跨类创建的匿名类无法访问目标类私有成员的原因及错误排查
问题原因与修正方案
嘿,我来帮你理清这个问题~你踩了一个Java新手很容易混淆的点:把继承的匿名子类和外部类的匿名内部类搞混了!
为什么你的代码无法访问私有成员?
你写的匿名类是movie的子类(通过new movie() {...}创建的匿名子类),而Java的私有成员(private修饰的moviename)遵循封装规则:私有成员只能在定义它的类本身内部访问,子类(哪怕是匿名子类)都没有直接访问父类私有成员的权限。
而你听说的「匿名类可以访问外部类私有成员」,指的是另一种场景:匿名类作为外部类的内部类存在(比如是外部类的成员内部类、方法里的局部内部类),这种情况下内部类和外部类是「包含关系」,而非继承关系,Java允许内部类访问外部类的私有成员。
两种修正方案
方案1:通过继承访问——给父类加getter或修改访问权限
如果想继续用继承的匿名子类,可以给movie类添加一个获取私有成员的getter方法,或者把moviename的修饰符改成protected(允许子类访问):
class movie{ private String moviename="bahubali"; // 添加getter方法,提供访问私有成员的途径 public String getMoviename() { return moviename; } void display(){ System.out.println(moviename); } } public class InnerClass{ //main class public static void main(String[] args) { movie anonymous=new movie() { void display() { // 通过getter方法访问父类私有成员 System.out.println(getMoviename()+" in anonymous class"); } }; anonymous.display(); } }
方案2:利用内部类特性——把匿名类放在movie类内部
如果想体验「匿名类访问外部类私有成员」的特性,可以把匿名类定义在movie类的内部(比如方法里的局部内部类),此时匿名类属于movie的内部类,就能直接访问私有成员:
class movie{ private String moviename="bahubali"; void display(){ // 这个匿名类是movie类的局部内部类,属于外部类的内部,可直接访问私有成员 Runnable showName = new Runnable() { @Override public void run() { System.out.println(moviename + " in anonymous inner class"); } }; showName.run(); } } public class InnerClass{ public static void main(String[] args) { movie m = new movie(); m.display(); } }
内容的提问来源于stack exchange,提问作者azeem mirza




