19

举个例子:

public void init() {
    final Environment env = new Environment();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
             env.close();
        }
     });
}

首先,env存储在哪里?是吗:

  • 由编译器复制到引用它的内部类的隐藏成员变量中
  • 复制到堆并在堆上引用
  • 留在堆栈上并以某种方式在那里引用
  • 别的东西

我的猜测是第一个选项。

其次,做任何由此产生的性能问题(而不是简单地创建env为类的成员变量并引用它),特别是如果您正在创建大量引用最终局部变量的此类内部类构造。

4

1 回答 1

19

是的,它们被复制了,这就是为什么你必须将变量声明为 final。这样,可以保证它们在复制完成后不会更改。

这与实例字段不同,即使不是最终字段也可以访问。在这种情况下,内部类获得对其用于此目的的外部实例的引用。

private Environment env;  // a field does not have to be final

public void init() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
             env.close();
        }
     });
}

其次,这样做会产生任何性能问题吗?

相比什么?您需要有字段或变量才能让您的内部类工作,而副本是一种非常有效的方法。无论如何,它只是一个“浅”副本:仅复制了对(在您的示例中)环境的引用,而不是环境本身。

于 2009-12-22T11:07:01.183 回答