美文网首页
Final 和方法中的内部类

Final 和方法中的内部类

作者: Happioo | 来源:发表于2019-07-14 16:19 被阅读0次

在 Java 的内部类的机制中,非 static 的内部类可以会持有外部类的 this 引用,因此可以访问外部类的资源,这一点还是挺自然的。

但有一点一直让我觉得很神奇,就是方法中的内部类可以访问方法的 final 形参和 final 本地变量,如下:

import javax.swing.*;

public class FooGUI {

    public static void main(String[] args) {
        //initialize GUI components
        final JFrame jf = new JFrame("Hello world!"); //allows jf to be accessed from inner class body
        jf.add(new JButton("Click me"));

        // pack and make visible on the Event-Dispatch Thread
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                jf.pack(); //this would be a compile-time error if jf were not final
                jf.setLocationRelativeTo(null);
                jf.setVisible(true);
            }
        });
    }
}

这份代码取自维基百科,main 方法里创建的匿名内部类中引用了 main 方法里的 JFrame jf 本地变量。客户端编程,像 Android 应用开发中由于常常要设置监听,回调,所以经常会用到这个特性。

那么这个特性是个什么原理呢,为什么能这么做呢,如果这个方法运行完了,它的栈帧就被移除了,里面的本地变量也都被清除了,这时候匿名内部类中再使用这个变量不会有问题吗?原来,在内部类中使用外部方法中的 final 本地变量和 final 形参时,编译器会去“捕获”它们,会存一份拷贝在内部类中,这样的话,即使方法的栈帧被清除了,内部类中仍然保存着它的拷贝,仍然能访问它。

至于,为什么这些变量要被修饰成 final,主要是为了维持一致性。因为实际上内部类和外部方法用的不是同一份变量,但从外部看来,它们还得像是同一份变量,如果允许改动这些变量的话,很可能会出现不一致的情况,所以用 final 修饰它们,让它们是不可变的。

在 Java 8 后,即使本地变量或方法参数不标记成 final,内部类中也能访问它们。但事实上,其实是和用 final 修饰一样的,同样还是不允许修改他们,只是不用 final 修饰而已。如果有修改它们的行为,那么编译时就会报错。这种变量称为 effectively final 变量。

相关文章

  • Final 和方法中的内部类

    在 Java 的内部类的机制中,非 static 的内部类可以会持有外部类的 this 引用,因此可以访问外部类的...

  • Java 中的方法内部类

    Java 中的方法内部类 方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内...

  • 方法内部类

    定义在外部类方法中的内部类,也称局部内部类方法内部类1.定义在方法内部,作用范围也在方法内2.和方法内部成成员使用...

  • 内部类

    成员内部类 局部内部类(定义在方法内和定义在作用域内的类) 匿名内部类

  • 匿名内部类中使用的局部变量设置为final

    匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型 1. 这里所说的“匿名内部类”主要是指在...

  • Java内部类

    代码中包含成员内部类、内部类的同名变量访问、局部内部类、局部内部类final、匿名内部类

  • java面试总结

    final匿名内部类内部类并不是直接调用方法传递的参数,而是利用构造器对外部类方法形式参数进行复制,而内部类自己方...

  • 接口,lambda表达式和内部类

    接口,lambda表达式和内部类 接口 定义 接口特性 可以包含常量(public static final)方法...

  • Java 内部类

    内部类包括成员内部类、方法内部类、*静态内部类、匿名内部类*。 内部类的作用 由于内部类的实现和外部类没有关系,内...

  • 类的编译期与运行期

    非静态内部类 非静态内部类到底可以有静态属性吗? static成员变量,或者static final常量 非静态内...

网友评论

      本文标题:Final 和方法中的内部类

      本文链接:https://www.haomeiwen.com/subject/fhfikctx.html