19

Take the following example:

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

Firstly, where is env stored? Is it:

  • copied by the compiler into a hidden member variable of the inner class that references it
  • copied to, and referenced on, the heap
  • left on the stack and somehow referenced there
  • something else

My guess is the first option.

Secondly, do any performance issues that arise from doing this (rather than simply creating env as a member variable of the class and referencing it as such) particularly if you are creating large numbers of such inner class constructs that reference final local variables.

Chip Uni
  • 7,454
  • 1
  • 22
  • 29
Joel
  • 29,538
  • 35
  • 110
  • 138

1 Answers1

19

Yes, they are copied, which is why you have to declare the variable as final. This way, they are guaranteed to not change after the copy has been made.

This is different for instance fields, which are accessible even if not final. In this case, the inner class gets a reference to the outer instance that it uses for this purpose.

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

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

Secondly, do any performance issues that arise from doing this?

Compared to what? You need to have the field or variable around for your inner class to work, and a copy is a very efficient way. It is only a "shallow" copy anyway: just the reference to the (in your example) Environment is copied, not the Environment itself.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • So can I assume there are no performance issues that arise from doing this? – Joel Dec 22 '09 at 11:08
  • My personal pet peeve in this area is that the references to the outer instance (used to access fields, not variables, which are copied) may be a problem, if they are not needed: http://stackoverflow.com/questions/758570/is-it-possible-to-make-anonymous-inner-classes-in-java-static – Thilo Dec 22 '09 at 11:15
  • compared to referencing it as a member variable. If it's copied, then, my assumption is that there are no performance implications. – Joel Dec 22 '09 at 11:17
  • yes, it is the same (just less typing), as you are behind the scenes in fact referencing a synthetic member variable that the compiler has created for you in the inner class to hold the copy of the final variable. – Thilo Dec 22 '09 at 11:20
  • 2
    you will get my upvote if you add a reference or work that made you belive this. – David Waters Dec 22 '09 at 13:00