代码之家  ›  专栏  ›  技术社区  ›  Mike Daniels

在Java内部匿名类中引用封闭类的非最终字段

  •  3
  • Mike Daniels  · 技术社区  · 15 年前

    在爪哇,我知道这样做是可能的:

    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();
        }
    }
    

    在这种情况下,我的匿名 工作 正在引用封闭类的非最终字段。当作业运行时,我是否可以看到 greeting 创建作业时的字段,还是执行作业时的字段?我想我知道答案,但我认为这是一个有趣的问题,一开始我和几个同事对自己进行了几分钟的猜测。

    3 回复  |  直到 15 年前
        1
  •  9
  •   erickson    15 年前

    greeting 当匿名者 Job 执行。

    这个 final 只有局部变量才需要修饰符,而不是成员变量。

        2
  •  1
  •   Tom Hawtin - tackline    15 年前

    您正在通过(外部)访问字段 this )你可以想到 作为有效的 final 局部变量。只有当地人 最终的 ,指向的对象不是(必然)常量。假设一个局部变量的值与 应该很清楚。

    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
  •  -1
  •   MostafaEweda    15 年前

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

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