【问题标题】:Referring to non-final fields of an enclosing class inside an anonymous inner class in Java在 Java 中的匿名内部类中引用封闭类的非最终字段
【发布时间】:2010-02-12 01:02:53
【问题描述】:

在 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 指的是封闭类的非最终字段。当作业运行时,我会看到创建作业时的 greeting 字段的值,还是执行时的值?我想我知道答案,但我认为这是一个有趣的问题,起初它让我和几个同事怀疑了几分钟。

【问题讨论】:

    标签: java closures anonymous-types anonymous-class


    【解决方案1】:

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

    final 修饰符仅适用于局部变量,而不是成员变量。

    【讨论】:

    • 这就是我怀疑它的工作方式。顺便说一句,我明确提到 non-final 字段的唯一原因是因为如果该字段是 final 则行为是明确的。
    • 是的。我们认为在 SO 中记录是一个很好的问题。迈克,你应该接受这个。
    【解决方案2】:

    您正在通过(外部)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();
        }
    }
    

    【讨论】:

      【解决方案3】:

      final修饰符应用于局部变量只是为了为内部类的每个实例提供变量,所以我们使用: 最后的字符串问候;

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2011-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-16
        • 1970-01-01
        相关资源
        最近更新 更多