有没有办法让Java中的匿名内部类“失去”它们的范围?

时间:2009-03-23 11:25:56

标签: java closures inner-classes

当我将匿名内部类传递给函数时,我可以从该类的方法中引用当前作用域中的变量,如下所示:

class Caller {
    private Object callerPrivate;

    // ...

    public void someMethod() {
        final String callerLocal = "Eyes only";

        ISomeInterface anon = new ISomeInterface() {
                                     public void doSomethingInterfacy {
                                         System.out.println(callerPrivate.toString());
                                         System.out.println(callerLocal);
                                     }
                                  };
        // this is some other object that puts ISomeInterfaces in a queue
        // and makes them doSomethingInterfacy later
        myCallManager.enqueue(anon);
    }
}

现在,在上面的someMethod运行之后,调用者和带有小动画的队列可以分开,并且据我所知,JVM保持所有引用都是直的,这样总是有效。

但是,例如,如果队列被序列化,程序关闭并重新启动,之后队列被反序列化并且其中的项目将被运行,Caller实例很久就被遗忘了?

还有其他方法可以让周围的对象和匿名的内部类以一种在anon类内部调用的方式分离出来吗?

2 个答案:

答案 0 :(得分:6)

不要序列化本地类,因为(a)文档这样说,(b)序列表示不稳定(它们没有稳定的起始名称)。

如果您不希望实例保留外部字段和使用的最终本地字段,请使用(静态)嵌套类或外部类。对于(Java)序列化,您可以使用writeReplace来序列化串行代理对象。

答案 1 :(得分:2)

不要忘记您的匿名内部类包含隐式的 this 引用。即对周围阶级的提及。

因此,如果你序列化你的内部类,那么将会引用你的外部类。如果使用XStream进行序列化并查看XML输出,则可以清楚地看到这一点。