Are all final variables captured by anonymous classes?

后端 未结 4 1241
北恋
北恋 2021-02-13 00:03

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 {

    // othe         


        
4条回答
  •  南笙
    南笙 (楼主)
    2021-02-13 00:20

    Only obj1 is captured.

    Logically, the anonymous class is implemented as a normal class something like this:

    class Anonymous1 extends SomeCallbackClass {
        private final Outer _outer;
        private final SomeObject obj1;
        Anonymous1(Outer _outer, SomeObject obj1) {
            this._outer = _outer;
            this.obj1 = obj1;
        }
        @Override
        public void onEvent() {
             System.out.println(this.obj1.getName());
        }
    });
    

    Note that an anonymous class is always an inner class, so it will always maintain a reference to the outer class, even if it doesn't need it. I don't know if later versions of the compiler have optimized that away, but I don't think so. It is a potential cause of memory leaks.

    The use of it becomes:

    someManager.registerCallback(new Anonymous1(this, obj1));
    

    As you can see, the reference value of obj1 is copied (pass-by-value).

    There is technically no reason for obj1 to be final, whether declared final or effectively final (Java 8+), except that if it wasn't and you change the value, the copy wouldn't change, causing bugs because you expected the value to change, given that the copying is a hidden action. To prevent programmer confusion, they decided that obj1 must be final, so you can never become confused about that behavior.

提交回复
热议问题