博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内部类如果要引用外部类的变量,则该变量必须为final
阅读量:4053 次
发布时间:2019-05-25

本文共 1072 字,大约阅读时间需要 3 分钟。

 今天程序中突然贵蹦出来一个这么错误:

Cannot refer to a non-final variable service inside an inner class defined in a different method

上网查最一下才知道:

内部类引用了一个非final的变量,

内部类如果要引用外部类的变量,则该变量必须为final,这是规定

 

(我觉得应该是生命周期的问题! 如果你引用的外部变量不是一个final 的! 那么,可能在你的内部类运行期间 引用的外部变量 超出了生命周期之外(方法执行完了 ,可是内部类对象却还在引用该局部变量!))

涉及到闭包(closure)的概念。

不同语言对闭包选择了不同的支持,相比之下,C#中就能够在匿名函数中引用非final的外部变量,例如这篇帖子中提到的C#代码:

List
> actions = new List
>();int variable = 0;while (variable < 5){ actions.Add(() => variable * 2); ++ variable;}foreach (var act in actions){ Console.WriteLine(act.Invoke());}

这一行:

actions.Add(() => variable * 2);

就在匿名方法内引用了外部局部变量: variable.

 

但同时也引起了一个奇怪的问题,上面的C#代码,我们期望的结果应该是输出"0, 2, 4, 6, 8"才对,结果却是10个零。

 

原因就是C# compiler 在所闭的包内圈入了对variable的引用,然后当运行

Console.WriteLine(act.Invoke());

 

时,variable值已经变成5,结果输出为10个零。

 

这种特性多少有点令人意外,可能java正是为了避免这种情形,于是强制规定闭包内引用的外部局部变量必须为final,想象一下如果上例中variable 为final的话,自然就不会写出上面的代码,造成类似的意外了。

 

另外,上例中如果你希望达到输出"0, 2, 4, 6, 8"的效果,可以:

while (variable < 5){    int copy = variable;    actions.Add(() => copy * 2);    ++ variable;}

 

转载地址:http://cqtci.baihongyu.com/

你可能感兴趣的文章
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
机器学习实战之决策树(一)
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[LeetCode By Python]121. Best Time to Buy and Sell Stock
查看>>
[LeetCode By Python]136. Single Number
查看>>
Android/Linux 内存监视
查看>>
Android2.1消息应用(Messaging)源码学习笔记
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
pidgin-lwqq 安装
查看>>