引用Java中匿名内部类中的封闭类的非final字段

时间:2010-02-12 01:02:54

标签: java closures anonymous-types anonymous-class

在Java中,我知道可以这样做:

public class Greeter {
    public void greetEventually() {
        final String greeting = "Hello!";
        Job j = new Job() {
            public void run() {
                System.out.println(greeting);
            }
        };
        j.schedule();
    }
}

这会在将来的某个时刻执行匿名Job。这是有效的,因为允许匿名类引用封闭范围中的最终变量。

我不确定的是以下情况:

public class Greeter {
    private String greeting;

    // ... Other methods that might mutate greeting ...

    public void greetEventually() {
        Job j = new Job() {
            public void run() {
                System.out.println(greeting);
            }
        };
        j.schedule();
    }
}

在这种情况下,我的匿名Job指的是封闭类的非final字段。作业运行时,我会看到greeting字段的值,就像创建作业时的值一样,还是它在执行时的值?我想我知道答案,但我认为这是一个有趣的问题,起初它让我和几个同事再次猜测自己几分钟。

3 个答案:

答案 0 :(得分:9)

当匿名greeting执行时,您会看到Job的值。

final修饰符仅对局部变量而非成员变量是必需的。

答案 1 :(得分:1)

您正在通过(外部)this)访问该字段。您可以将this视为有效的final局部变量。只有本地是final,指向的对象不一定(必然)。想象一个与this具有相同值的局部变量,它应该是清楚的。

public class Greeter {
    private String greeting;

    // ... Other methods that might mutate greeting ...

    public void greetEventually() {

        private final Greeter greeter = this; // <---

        Job j = new Job() {
            public void run() {
                System.out.println(   greeter.greeting   ); // <---
            }
        };
        j.schedule();
    }
}

答案 2 :(得分:-1)

final修饰符仅应用于局部变量,以便为内部类的每个实例提供变量,因此我们使用: 最后的字符串问候语;

当您只需要变量的一个实例时(如常量或公共资源的情况),请使用: 私人字符串问候语;