美文网首页
内部类引用外部类的局部变量要用final修饰

内部类引用外部类的局部变量要用final修饰

作者: 饺子呀呀 | 来源:发表于2018-01-25 20:11 被阅读0次

为什么内部类引用外部类的局部变量时,此变量要用final修饰

如图

   public void test() {
   
       final int i = 3;
       
       runOnUiThread(new Runnable() {
           @Override
           public void run() {
               mTvShow.setText(String.valueOf(i));
           }
       });
   }
  

上面的代码是使用了匿名内部类的方式。Runnable是一个接口,此内部类实现了Runnable方法,重写了接口里面的run()方法,方法内引用了外部方法体内的局部变量 i,这个时候i只能被定义为final变量,否则编译会报错。

我们可以从JVM的角度去解释这个现象,在编译期的时候,所有的类都会被编译成Class文件。匿名内部类也会被编译成Class文件。但是上面的例子的内部类编译会和我们所知道的普通类编译方式会有些不同。
  大多数的类在编译的时候,需要知道每个方法需要为其所有的局部变量分配多少内存。所以它会去检查方法内定义的变量,从而确定此方法到真正运行的时候需要在栈中开辟多少内存。但这只是计算需要多少内存,真正分配内存是在运行期。
  所以可以发现匿名内部类不同的是,虽然方法中的i没有定义,但是在编译期会给它分配额外的内存,并给它赋与外部的i同一个值。但是此变量已经不是外部的局部变量了。在内存的角度上看,匿名内部类的i实际上不是外部的i,它们使用的内存空间都不同,只是它们的值相同
  其实本质上来说,完全可以当作两个不同的变量去使用,但是Java的设计人员可能想要保持一致性,因为Java的初学者在不了解其中真正的机制的时候,会以为他们就是同一个变量,所以干脆就把变量强制定义为final,这样变量就不能被重新赋值,营造一种他们是同一个变量的“假象”。

为什么引用外部类的成员变量的时候,又不用final修饰呢?

有一点要注意,当引用的不是局部变量而是外部类的成员变量的时候,不一样要用final修饰,因为它不需要像上面说的那样需要在栈中重新开辟一个空间,而是内部类持有外部类的引用,可以直接引用外部类的成员变量。

与C/C++的不同

在C++中,同样的现象,引用外部类的局部变量时,是不用加final了。其根本原因是出在,C++在编译期的时候就进行动态连接了,而Java是在运行期的时候才进行动态连接。
  说白了,就是C++的编译时就已经分配好了空间,自然外部类和匿名内部类的i其实用的是同一块内存区域,是真正意义上的同个变量,所以不需要加final。

相关文章

  • 内部类引用外部类的局部变量要用final修饰

    为什么内部类引用外部类的局部变量时,此变量要用final修饰 如图 上面的代码是使用了匿名内部类的方式。Runna...

  • 匿名内部类问题

    匿名内部类访问的外部类局部变量为什么要用final 修饰,jdk8为啥不需要了? 匿名内部类访问的外部类局部变量为...

  • 匿名内部类的使用

    1.匿名内部类中局部变量的使用 在JDK8中,匿名内部类使用局部变量不再要求局部变量使用final修饰,那么是否我...

  • Java

    JDK8之前,匿名内部类访问局部变量,局部变量为什么必须要用 final 修饰。 我们先来看一段代码: 原因是:因...

  • 07.成员内部类的修饰符

    成员内部类 成员内部类可以使用的修饰符:private,public,procted,final,static,a...

  • javap反编译探寻内部类如何捕获final变量

    final 关键字的用法很多,其中有一种是修饰局部变量,使之能在内部类中使用。 显然,为了能在内部类中使用,fin...

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

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

  • java内部类

    开篇问题 为什么需要内部类? 为什么内部类,会持有外部类的引用? 为什么匿名内部类使用到外部类方法中的局部变量时需...

  • (java知识小总结二)2018-05-31

    5.2Java 中的静态内部类:静态内部类是 static 修饰的内部类 特点:(1)、 静态内部类不能直接访问外...

  • ★08.内部类

    如果要从外部类的成员方法之外访问内部类,需要用outer.inner的方式引用。 内部类引用自己的方式是this,...

网友评论

      本文标题:内部类引用外部类的局部变量要用final修饰

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