最近有一个疑惑:为什么局部内部类中访问同一方法中的变量,该变量一定要是final修饰的
        首先,我们看一个局部内部类的例子:    
        class OutClass {
         private int temp = 11;
        
         public void outTest(final int x) {
          class InClass {
           public void innerTest() {
            System.out.println(x);
            System.out.println(temp);
           }
          }
          new InClass().innerTest();
         }
        }
        这里有一个外部类OuterClass和一个内部类InClass,内部类访问了外部类的一个方法中的一个局部变量x,在这里,x必须是final的,否则会报错:
        Cannot refer to a non-final variable x inside an inner class defined in a different method
       下面来分析下这个问题:
      追究其根本原因就是作用域中变量的生命周期导致的;
       首先需要知道的一点是:内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁.
    这里就会产生问题:当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有没有人再引用它时,才会死亡)。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量。为了解决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以访问它,实际访问的是局部变量的”copy”。这样就好像延长了局部变量的生命周期。
       问题又出现了:将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢?
       就将局部变量设置为final,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量和方法的局部变量的一致性。这实际上也是一种妥协。
      若变量是final时:
若是基本类型,其值是不能改变的,就保证了copy与原始的局部变量的值是一样的;
若是引用类型,其引用是不能改变的,保证了copy与原始的变量引用的是同一个对象。
这就使得局部变量与内部类内建立的拷贝保持一致。
  

为什么局部内部类中访问同一方法中的变量,该变量一定要是final修饰的的更多相关文章

  1. Android(java)学习笔记150:为什么局部内部类只能访问外部类中的 final型的常量

    为什么匿名内部类参数必须为final类型: 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变 ...

  2. Android(java)学习笔记93:为什么局部内部类只能访问外部类中的 final型的常量

    为什么匿名内部类参数必须为final类型: 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变 ...

  3. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  4. Java学习笔记23---内部类之局部内部类只能访问final的局部变量

    局部内部类是定义在方法体或代码块中的类,在笔记19中已有过简单介绍. 今天要讨论的是局部内部类为什么只能访问为常量的局部变量. 作者: 博客园--蝉蝉 请尊重作者劳动成果,转载请在标题注明“转载”字样 ...

  5. 从垃圾回收机制解析为什么局部内部类只能访问final修饰的局部变量以及为什么加final能解决问题

    我们先稍微看一下代码: 从这里的提示可以看到,必须要将a的修饰符变为final才行. 现在笔者就这一结果做出自己的分析: 首先来说,我们知道,方法被调用时会执行,当执行的时候,方法中的局部变量会加载到 ...

  6. java 访问器方法中对象引用的问题

    "注意不要编写返回引用可变对象的访问器方法".因为会破坏类的封装性,引用的内容可能会被改变,产生业务逻辑上的错误. 什么是可变对象? 先要搞清楚java中值传递和引用传递的问题,总结如下: 1.对象就 ...

  7. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  8. 详解SpringMVC中Controller的方法中参数的工作原理——基于maven

    转自:http://www.tuicool.com/articles/F7byQn 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

  9. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

随机推荐

  1. Python提升“技术逼格”的6个方法

    1 列表生成式和生成器 from numpy import randoma = random.random(10000) lst = []for i in a: lst.append(i * i) # ...

  2. leaflet视频监控播放(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  3. Android BGradualProgress 多种渐变、直角or弧角、进度条、加载条

    可实现多种渐变.直角or弧角.进度条.加载条 (Various gradient, right or arc angle, progress bar and loading bar can be re ...

  4. NLP之语言模型

    参考: https://mp.weixin.qq.com/s/NvwB9H71JUivFyL_Or_ENA http://yangminz.coding.me/blog/post/MinkolovRN ...

  5. PHP实现微信扫码自动登陆与注册,参考实例

    微信开发已经是现在phper必须要掌握的一项基本的技术了,其实做过微信开发的都知道微信接口非常的强大做起来也非常的简单,这里我们一起来看一个微信自动登陆注册的例子. php 微信扫码 pc端自动登陆注 ...

  6. Mysql - 高可用方案之MMM(二)

    一.概述 上一篇博客中(https://www.cnblogs.com/ddzj01/p/11535796.html)介绍了如何搭建MMM架构,本文将通过实验介绍MMM架构的优缺点. 二.优点 1. ...

  7. unity3D开发环境搭建

    前言 本文记录unity3D开发环境的搭建 unity安装 unity有中文官网(https://unity.cn/),很贴心,ide工具我们选择下载安装中国区增强版,下载地址:https://uni ...

  8. 【Beta阶段】第十二周Scrum会议

    [Beta阶段]第十二周Scrum会议 本次会议为第十二周第一次Scrum Meeting,会议对Beta阶段工作进行了总结,针对Beta阶段还未完成的问题进行了讨论. 会议时间为2019.12.3. ...

  9. Windows系统Git配置教程(Git配置git config)

    Windows系统Git配置教程(Git配置git config)   在很多Git配置教程中,多是安装完毕后就告诉大家要配置用户名和邮箱,但是这个配置是保存在哪里呢,配置后面的参数有什么不同呢,下面 ...

  10. 深挖的Java源代码之Integer.parseInt()vs Integer.valueOf()

    Integer.parseInt()和Integer.valueOf()都是用来将String转换为Int的,但是为什么Java会提供两个这样的方法呢,他们如果是同样的操作,岂不是多此一举? 我们来深 ...