Java 最终局部变量存储在哪里?

2022-09-02 13:33:20

举个例子:

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

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

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

我的猜测是第一种选择。

其次,执行执行此操作(而不是简单地创建为类的成员变量并引用它)引起的任何性能问题,尤其是在创建大量引用最终局部变量的内部类构造时。env


答案 1

是的,它们是复制的,这就是为什么您必须将变量声明为 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();
        }
     });
}

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

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


答案 2

推荐