局部内部类(即:定义在方法中的内部类),访问方法中的局部变量
: 局部变量的生命周期与对象的生命周期的不一致性!方法在执行完方法的局部变量就消失,而内部类如果有引用还是存在的,那么将找不到变量。此时设计的做法是复制一份参数,为了保证复制的参数和方法的变量的一致,就需要保证其引用的对象不变,否则方法的局部变量的引用指向修改了,但是内部类却不知道
 1 public class Outer {
 2     public static void main(String[] args) {
 3         Outer outer = new Outer();
 4         Inner inner = outer.getInner("Inner", "gz");
 5         System.out.println(inner.getName());
 6     }
 7
 8     public Inner getInner(final String name, String city) {
 9            //final String name
10         return new Inner() { //或者定义一个内部线程,如果非final,引用指向改变了,内部类是无法知道的,因为编译时复制参数时参数被确定了引用指向
11             private String nameStr = name;
12
13             public String getName() {
14                 return nameStr;
15             }
16         };
17     }
18 }
19
20 interface Inner {
21     String getName();
22 } 

内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。 
这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是final来规避这种莫名其妙错误的存在。”
 (简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变)
详细的解释是:

局部变量的生命周期与局部内部类的对象的生命周期的不一致性!

1)  设方法f被调用,从而在它的调用栈中生成了变量i,此时产生了一个局部内部类对象inner_object,它访问了该局部变量i .当方法f()运行结束后,局部变量i就已死亡了,不存在了.但:局部内部类对象inner_object还可能   一直存在(只能没有人再引用该对象时,它才会死亡),它不会随着方法f()运行结束死亡.这时:出现了一个"荒唐"结果:局部内部类对象 inner_object要访问一个已不存在的局部变量i!

2)  如何才能实现?当变量是final时,通过将final局部变量"复制"一份,复制品直接作为局部内部中的数据成员.这样:当局部内部类访问局部变量 时,其实真正访问的是这个局部变量的"复制品"(即:这个复制品就代表了那个局部变量).因此:当运行栈中的真正的局部变量死亡时,局部内部类对象仍可以 访问局部变量(其实访问的是"复制品"),给人的感觉:好像是局部变量的"生命期"延长了.

那么:核心的问题是:怎么才能使得:访问"复制品"与访问真正的原始的局部变量,其语义效果是一样的呢? 
当变量是final时,若是基本数据类型,由于其值不变,因而:其复制品与原始的量是一样.语义效果相同.(若:不是final,就无法保证:复制品与原始变量保持一致了,因为:在方法中改的是原始变量,而局部内部类中改的是复制品)

当 变量是final时,若是引用类型,由于其引用值不变(即:永远指向同一个对象),因而:其复制品与原始的引用变量一样,永远指向同一个对象(由于是 final,从而保证:只能指向这个对象,再不能指向其它对象),达到:局部内部类中访问的复制品与方法代码中访问的原始对象,永远都是同一个即:语义效 果是一样的.否则:当方法中改原始变量,而局部内部类中改复制品时,就无法保证:复制品与原始变量保持一致了(因此:它们原本就应该是同一个变量.)

转载于:https://www.cnblogs.com/straybirds/p/5211047.html

内部使用final参数的原因相关推荐

  1. C语言多维数组做函数参数退化原因大剖析

    多维数组做函数参数退化原因 多维数组做函数参数退化原因大剖析 多维数组做函数参数退化原因大剖析 //证明一下多维数组的线性存储 //线性打印 void printfArray411(int *arra ...

  2. 控制台报400、500内部服务器错误是什么原因?怎么解决?

    控制台报400.500内部服务器错误是什么原因?怎么解决? 状态码为400时 显示Bad Request,此时你可以看一下你的控制台->网络部分 -> 数据返回是不是后端要求上传的数据格式 ...

  3. Docker容器内部无法访问外网原因之一

    问题描述 部署了一个Docker环境,宿主机可以访问Internet,启动了一个容器发现容器里的服务无法访问Internet,Docker网络使用的是桥接(bridge)模式. 问题分析 使用Dock ...

  4. ORA-00600_内部错误代码_参数19004

    监控信息显示报如下错误:  ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [], [], [], [], [], [] 1.查看报错信息 查看 ...

  5. android final参数,Android应用开发之Android Jetpack-Navigation 使用中参数的传递方法

    本文将带你了解Android应用开发之Android Jetpack-Navigation 使用中参数的传递方法,希望本文对大家学Android有所帮助. 由于使用了Navigation,导致Frag ...

  6. python 基于UDP协议的socket 报错:WinError 10022 提供了一个无效的参数(原因:服务端没有绑定ip)

    如图: 原因: 服务端socket没有绑定ip和端口,绑定一下就好了 udp_server_sock.bind(ip_port) 参考文章:python socket 使用错误:WinError 10 ...

  7. STM32F103使用内部Flash保存参数

     在我们应用开发时,经常会有一些程序运行参数需要保存,如一些修正系数.这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能.将这类数据存在 ...

  8. 斗鱼App全网下架,官方表示内部优化调整,真实原因是...

    微信又改版了,为了方便第一时间看到我们的推送,请按照下列操作,设置"置顶":点击上方蓝色字体"程序员之家"-点击右上角"-"-点击" ...

  9. ORA-00600: 内部错误代码,参数: [qctcte1], [0], [], [], [], [], [], []

    今天遇到此错,一头无数.百度到http://ms.itpub.net/redirect.php?fid=2&tid=1187496&goto=nextoldset 此牛人滴解答,备忘之 ...

最新文章

  1. Python安装时我遇到的一些问题
  2. 产品经理说以后接口不找你写了!啥情况?我要凉了?
  3. 自定义Spark Partitioner提升es-hadoop Bulk效率——续
  4. 如何正确理解近似点梯度下降算法
  5. 【渝粤题库】国家开放大学2021春1044合同法题目
  6. Microsoft经典平面广告we see
  7. Matlab中图像函数大全
  8. android expandablelistview横向,expandableListView 总结
  9. python 以图搜图1688_以图搜图(一):python aHash算法
  10. 爬虫进阶:CrawlSpider爬取169ee全站美女图片
  11. java虚拟机 for win7 64位_最新win7 64位旗舰版安装版下载(64位iso镜像)
  12. react加水印_图片添加水印
  13. 5G核心网技术基础自学系列 | (增强型)专用核心网
  14. [IOS]Presenting modal in iOS 13 fullscreen
  15. 7.3.1 B树及其基本操作
  16. 如何查询linux的系统版本
  17. JQuery选择器细节-遁地龙卷风
  18. HikariPool-1 - Exception during pool initialization.的解决方法
  19. Fluent Bit的下载量达到10亿!
  20. Microsoft SQL Server 2000 简体中文企业版+SP4升级补丁

热门文章

  1. 深入研究Java类加载机制
  2. 图结构练习——BFS——从起始点到目标点的最短步数
  3. Android内存分析和调优
  4. linux网络编程一:主机字节序与网络字节序的的判断
  5. WEB 3.0(非技术版)
  6. springboot自动配置流程
  7. 剑指offer十:矩形覆盖
  8. mybaits一:初步认识mybatis
  9. Linux centos 下apache(httpd)编译安装
  10. (笔试题)将数组分成两组,使两组的和的差的绝对值最小