Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are all final variables captured by anonymous classes?

I thought I knew the answer to this, but I can't find any confirmation after an hour or so of searching.

In this code:

public class Outer {

    // other code

    private void method1() {
        final SomeObject obj1 = new SomeObject(...);
        final SomeObject obj2 = new SomeObject(...);
        someManager.registerCallback(new SomeCallbackClass() {
            @Override
            public void onEvent() {
                 System.out.println(obj1.getName());
            }
        });
    }
}

Assume that registerCallback saves its parameter somewhere, so that the object of the anonymous subclass will live for a while. Obviously this object has to maintain a reference to obj1 so that onEvent will work if it is called.

But given that the object doesn't use obj2, does it still maintain a reference to obj2, so that obj2 can't be garbage-collected while the object lives? I was under the impression that all visible final (or effectively final) local variables and parameters were captured and thus couldn't be GC'ed as long as the object was alive, but I can't find anything that says one way or the other.

Is it implementation-dependent?

Is there a section in the JLS that answers this? I wasn't able to find the answer there.

like image 684
ajb Avatar asked Nov 08 '18 08:11

ajb


People also ask

What is true about anonymous class?

1. Which is true about an anonymous inner class? A. It can extend exactly one class and implement exactly one interface.

Which of the following is true about the anonymous inner class?

18) Which of the following is true about the anonymous inner class? Explanation: Anonymous inner classes are the same as the local classes except that they don't have any name. The main use of it is to override methods of classes or interfaces.

Can anonymous class access local variable?

An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final. Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name.

Do anonymous classes have instances?

Anonymous classes are inner classes with no name. Since they have no name, we can't use them in order to create instances of anonymous classes. As a result, we have to declare and instantiate anonymous classes in a single expression at the point of use. We may either extend an existing class or implement an interface.


1 Answers

The language spec has very little to say about how anonymous classes should capture variables from their enclosing scope.

The only especially relevant section of the language spec that I can find is JLS Sec 8.1.3:

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.)

(Anonymous classes are inner classes)

It does not specify anything about which variables the anonymous class should capture, or how that capturing should be implemented.

I think it is reasonable to infer from this that implementations need not capture variables that aren't referenced in the inner class; but it doesn't say they can't.

like image 79
Andy Turner Avatar answered Nov 16 '22 03:11

Andy Turner