【问题标题】:Access anonymous outer class without storing in variable?访问匿名外部类而不存储在变量中?
【发布时间】:2012-04-02 03:58:44
【问题描述】:

有没有办法访问匿名外部类? ClassName.this 可以访问一个普通的类。这不起作用,因为匿名类显然没有名称。我也尝试使用扩展类/接口(如 Runnable.this),但它似乎不会以这种方式工作。

我确信这可能不是最好的编码风格,我只是好奇是否可以不将外部的这个存储在变量中。

例如,注意outer.this:

public class A
{
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (outher.this) {
                            outher.this.notify();
                        }
                    }
                }).start();
                try {
                    synchronized (this) {
                        wait();
                    }
                } catch (final InterruptedException ex) {}
            }
        }).start();
    }
}

【问题讨论】:

    标签: java syntax anonymous-class


    【解决方案1】:

    不,没有办法从任何地方访问匿名类,除了从它们内部(即,除了this 引用之外)。或者通过显式声明的变量。

    final Runnable r1 = new Runnable() {...};
    Runnable r2 = new Runnable() {
        public void run() {
             synchronized(r1) {...}
        }
    };
    

    【讨论】:

    • 你认为它可以与匿名类同步(this.getClass().getEnclosureClass())一起工作吗?
    • @Eric R. 我认为这会与 DiddiZ 发布的内容有所不同(也许您提出的正是 DiddiZ 真正想要的)。假设main 方法在许多不同的线程中同时执行。在 DiddiZ 的代码中,它们都将在不同的对象上同步 - 因此没有冲突。在您的代码中,它们都将在同一个对象上同步,因此会有一些冲突。但我怀疑你的代码是 DiddiZ 真正想要的。
    • 这是按类同步的,而不是按实例同步的。如果将同步监视器更改为 synchronized (this.getClass().getEnclosureClass() ) 和 synchronized(this.getClass()) (而不是 synchronized(this)),这将起作用。但是,如果您在同一个 Runnable 实例上运行多个线程,它将像静态同步 - 即跨所有实例。
    【解决方案2】:

    你可以添加一个方法来返回这个中间this。它会在范围内但不会隐藏(这是正确的术语吗?阴影?我忘记了。)。

    public static void main(String[] args) {
        new Thread(new Runnable() {
            Runnable middleThis() { return this; } // <-- this
            @Override
            public void run() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (middleThis()) {
                            middleThis().notify();
    

    注意,虽然匿名内部类没有名字,但它们仍然是类型。因此添加成员对直接表达式 (new X() { Y z; }.z) 和内部可见。你不能这样做middleThis().middleThis()

    【讨论】:

    • 这是绕过“不存储在变量中”限制的巧妙方法。
    猜你喜欢
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    相关资源
    最近更新 更多