匿名类的方法意外地表现

时间:2016-03-19 21:44:45

标签: java

public class Solution {
    private String name;

    Solution(String name) {
        this.name = name;
    }

    private String getName() {
        return name;
    }

    private void sout() 
    {
        new Solution("sout")
        {
            void printName() 
            {
                System.out.println(getName());
            }
        }.printName();
    }

    public static void main(String[] args) {
        new Solution("main").sout();
    }
}

匿名类的方法意外行为。 如何制作方法sout来打印“sout”,现在打印“main”?

2 个答案:

答案 0 :(得分:3)

问题在于String getName()private

这意味着派生类的方法无法访问。

但是,匿名派生类不仅是派生的,而且它也是一个内部类。因此,该类可以访问外部类的私有成员。这就是main被打印的原因,而不是sout

要做到这一点,您需要做的就是让方法非私有:默认访问权限,protectedpublic可以正常使用。

Demo.

答案 1 :(得分:1)

你会用

System.out.println(super.getName());

Solution中有一个匿名内部类Solution,因此getName()隐式引用外部实例,因为该方法是私有的。

您还可以使getName受保护而不是私有。

解释有点令人讨厌。由于范围的原因,getName对于匿名类是可见的,但由于它是私有的,因此匿名类通常不会引用getName本身,因为它实际上是一个子类。

真正奇怪的情况是你有一个静态的嵌套子类:

class Example {
    private void sayHello() {
        System.out.println();
    }

    static class Subclass extends Example {
        Subclass() {
            // This is a compiler error
            // because it tries to call sayHello()
            // on an enclosing instance which doesn't
            // exist (as if Subclass is an inner class).
            sayHello();
        }
    }
}

我在回答有关static案例的问题的答案中完成了规范,这也解释了为什么"main"在此处打印出来:https://stackoverflow.com/a/28971617/2891664