内部类局部方法调用为啥要final修饰?

目录

一、方法的局部变量被引用内部类为啥final修饰

二、Java 匿名类引用外部类成员变量为什么又不需要final修饰?


 


一、方法的局部变量被引用内部类为啥final修饰


void test() throws InterruptedException {
        //开始执行方法
        Student student = new Student();
        student.setAge(1);
        System.out.println(System.identityHashCode(student));
        //执行内部类
        new InnerInterfaceTest() {
            @Override
            public void print() {
                System.out.println(System.identityHashCode(student));
                outStr = "adsadsdas";
                System.out.println("innerclass:" + student.getAge());
                System.out.println("innerclass:" + outStr);

            }
        }.print();
      //执行余下方法
    }

对于上图代码,由于内部类和方法的执行的顺序不同可能会出现如下两种截

然不同的顺序,我们期望的结果是第一幅图结果。对于内部类参数的传递有两种方

式,第一种是capture-by-reference,另外一种是capture-by-value,如果是按照第一

个图的执行顺序,不管哪种传值方式都是会正确的将值专递给内部类,而且不会影响

结果。如果按照第二幅图执行顺序,可能会出现npe。

如果按照capture-by-reference:

如果采用capture-by-reference闭包方式,则a赋值给a1,a1

和a应该是同一个引用的,不会再内部类在创建一个新的引用,如果匿名内部类

执行的还未结束,但是局部已经执行结束,如第二幅图:1->2->3->4->5->6,会出一个

问题,a这个方法已经结束了,对象a已经被收回,此时对于a1会出现npe,因此

capture-by-reference在此处不适合。

如果按照capture-by-value:

采用capture-by-value内部匿名类会复制一个引用,即a1和a不是同一个引用,但

是指向的是同一块堆内存地址,不会出现npe问题,但是会出现另外一个问题:4改变a执

行的内容匿名内部类感知不到,同样6改变内容外部方法感知不到,因此为了数据一致性

考虑,对于局部方法使用匿名内部类,强制加final修饰,解决数据一致性。

总结:

局部方法传参给匿名内部类,采用的是capture-by-value,而又为了保证数据的一

致性,迫不得已采用final修饰。

 

内部类局部方法调用为啥要final修饰?_第1张图片

二、Java 匿名类引用外部类成员变量为什么又不需要final修饰?

由于外部类的生命周期大于内部的生命周期,因此外部类的成员变量

是采用capture-by-reference,在外部成员变量销毁时,内部类引用的肯定是

早于外部类,就不会出现npe问题。

 

 

 

 

你可能感兴趣的:(java,匿名类)