java内部类引用外部类的变量时必须是final变量

智能枕头 睡觉和吃饭是一样重要的,一个人想要健康的体魄,不仅要饮食得当,更需要有一个好的睡眠质量。随着人们生活品质的提高,人们对于睡眠的要求越来越高,那么就非常需要一款舒适的枕头。为了适应市场的需求,我爱物联网推出了智能枕头。因为智能枕头可以给头部及颈椎一个良好的承托力,舒适、柔软、放松,让人更好的进入睡眠。 目录 一、智能枕头方案介绍 二、智能枕头的优点 三、智能枕头功能介绍 四、智能枕头APP开发 五、... 阅读详情

每次android的触发事件时总是遇到内部类中不能调用外部类的非final变量。。但不知道什么原因,然后今天看到一个帖子上的跟们说的不错。知道原来是关于类的生命周期的问题。

我的解决方法是将方法内的方法定义到方法外部来。。

       今天编写一个多线程程序,发现在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更广的生命周期,下面通过一个实例加以说明:

image


    如例中所示,在外部类Outer中声明了一个内部类TimerPrint,这个类中的方法引用了方法start中的一个局部变量testTxt

    逻辑上:因为该内部类出现在一个方法的内部,但实际编译时,内部类编译为Outer$1TimerPrint.class,这说明,外部类的这个方法和内部类是处于同一级别的。换句话说是非final变量和内部类的生命周期不一样!start被调用后,非final变量也会随之消失,就会出现内部类引用非法!

    实际做法:java编译器的行为是这样的(前提条件是该变量在内部类中被引用): 
    若定义为final,则java编译器则会在内部类TimerPrint内生成一个外部变量的拷贝,而且可以既可以保证内部类可以引用外部属性,又能保证值的唯一性。

       若不定义为final,则无法通过编译!(jdk1.6测试过)。因为编译器不会给非final变量进行拷贝,那么内部类引用的变量就是非法的!


下面看经过编译以后的字节码:

外部类编译后的字节码: 
image


内部类编译后的字节码: 
image


image


如果外部类中的变量d没有被内部类引用,则final为可选的,而且java编译器将不做特殊处理!!

加一个参数d 并且把它定义为非final类型,编译以后文件如下:

编译后的外部类class: 
image 

编译后的内部类class: 
image

由上可以看出,在方法内部定义内部类时,内部类如果调用了方法内的变量,则该变量必须被final修饰,否则就会因为在调用内部类时因为找不到所用的变量而报错!

【学习系列】SAP RAP 7:行为定义-Draft 本文介绍了RAP框架中的草稿表(Draft)功能及其应用。草稿表允许用户临时保存数据,在激活前不影响业务逻辑,支持保存继续、暂存和设备切换功能。草稿分为独占草稿(仅限同一用户编辑)和协作草稿(允许多用户协同编辑)。启用草稿需在行为定义和投影中包含标准action,并创建包含TotalETag等管理字段的草稿表。TotalETag确保草稿转换时活动数据未被修改,而ETagmaster则防止并发修改。文章通过OData调用示例详细说明了ETag验证过程,强调草稿功能由RAP框架自动处理,开发者只需关注定义和配置 阅读详情

相关推荐

一文带你完成ARMv8架构中的cache知识点

【摘要】 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处理器内核要复杂得多,其时钟速度可以快上几个数量级。但是,外部总线和内存设备的频率并没有扩大到同样的程度。有可能实现小块的片上SRAM,它可以以与内核相同的速度运行,但是与标准的DRAM块相比,这种RAM非常昂贵,因为后者的容量可以达到数千倍。在许多基于ARM处理器的系统中,访问外部存储器需要几十甚至几百个内核周期。 cache的技术背景 在最初开发ARM架构时,处理器的时钟速度和内存的访问速度大致相同。今天的处.

ABCCloud的博客 1853

Java内部类引用外部类中的局部变量为何必须是final问题解析

今天编写一个多线程程序,发现在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更广的生命周期,下面通过一个实例加以说明:     如例中所示,在外部类Outer中声明了

且听风吟的专栏 1万+

STM32与小米CyberGear微电机的CAN通信协议深度解析

本文深度解析STM32与小米CyberGear微电机的CAN通信协议,涵盖硬件连接、CAN总线配置、通信协议解析及多电机协同控制。重点介绍了基于STM32的电机控制实践,包括运动模式、速度与位置模式设置,以及数据反馈与故障诊断,为机器人及自动化设备开发提供实用指南。

www00的博客 359

内部类引用外部类的局部变量为什么必须是final

内部类引用外部类局部变量,必须保证外部类的局部变量为final的,因为内部类和外部类的局部变量生命周期不一样,外部类方法执行完该局部变量可能就没了,但该方法中的内部类可能还在执行(如线程),还要使用该变量,所以外部类变量设置为final的,变成常亮,使用的时候内部类可以复制一个副本过去,相当于就不使用该局部变量了。  ...

林海静的博客 1620

PDF批量加水印 与 去除水印实践

我们可以给PDF加图片水印或文字水印,要去除图片水印,一般只需要删除最后一个图片对象即可。要去除文字水印,需要保证主体内容和文字水印在/Contents中位于不同的对象内,这样我们只需要删除文字水印对应的对象即可删除水印。而对于主体内容和文字水印已经混合在一个对象时,本文的提供的方法则无能为力,需要进一步深入分析PDF细节。

小小明-代码实体的专栏 2756

TSEND_C指令错误代码解析与实战排错指南

本文详细解析西门子PLC中TSEND_C指令的常见错误代码,包括连接建立、参数配置、资源限制和网络通信等错误类型。针对错误代码80C4等典型问题提供实战排错指南,帮助工程师快速诊断和解决工业通信中的连接故障,提升系统可靠性。

backprop5master的博客 410

多线程变量传递,为什么要用final关键字

1、对于基本数据类型的,如byte short char int 等,赋值后被final修饰的变量不能改变。 2、对于引用数据类型,地址不能改变,但是地址中的值可以发生改变。(String和包装类除外) final关键字:必须要被初始化赋值,而且只能初始化一次. Final关键字在并发中的原理是:禁止cpu指令集重新排序,来保证对象的安全发布,防止对象引用被其他线程在对象被完全构造完成前拿到并使用. 可以理解为防止被其他线程的对象所使用. 总结理解:用final关键字修饰变量,保证变量初始化后的结果不被修

pvmsmfchcs的博客 3624

【视频编码学习】AVS3参考软件HPM-4.1简单配置运行

1、用Visual Studio2017打开HPM-4.1文件夹 2、找到文件夹目录下x86_windows文件夹,因为是在win上运行该代码 3、然后找到对应vs版本(我当时2017版)的解决方案sln文件,双击打开可以看到该解决方案下的全部项目。 4、重新生成解决方案时发现提示sdk版本问题,所以右键点击所有的项目,选择重定向项目,修改一下sdk版本。 ...

谦虚勤奋诚实感恩 3100

为什么java内部类访问局部变量必须声明为final?

先抛出让我疑惑了很久的一个问题 编程时,在线程中使用局部变量时候经常编译器会提示:局部变量必须声明为final package test; public class ThreadTest { public void function(String a) { new Thread(){ @Override public void run() { Syst

大树的学习之路 1万+

等时替代模型( Isotemporal Substitution Model)

文献阅读:Associations of sedentary time and physical activity with adverse health conditions: Outcome-wide analyses using isotemporal substitution model(该论文于2022年4月28日发表在柳叶刀子刊 EClinicalMedicine 上)

姚巨龙的博客 1万+

【KingSCADA】如何建立硬件系统及相关变量

本篇主要讲解如何定义设备,如何定义变量。KingSCADA3.8的采集系统是指负责和现场设备进行通讯,并采集现场数据和控制现场数据的模块,称之为采集器,也叫IOServer应用,它是一组独立的应用程序,可以脱离KingSCADA3.8软件,它依赖于KingSCADA3.8驱动产品,通过驱动与IO设备进行通讯。采集系统由通讯链路,设备,数据块组成。链路:链路是指计算机通过什么方式(接口)与设备进行连接,链路类别:串口,以太网,GPRS,Modem,通信卡,采集卡,无链路。

做有价值的事,积累有价值的笔记! 1万+

final 关键字 限定方法参数

当定义一个方法A, 1.如果参数是基本类型,并且参数用了final 来修饰 方法A里面对参数是不可以修改的,编译的时候就会报错。 如果参数不用final来修饰那么在方法里是可以修改该参数的,但是对于调用者来说 参数仍然不变没有影响、 打印出来的i 变量和str 变量都是main 方法里设置的。 2.如果参数是一个对象类型的那么这个对象是不可以在A方法里从新N

shukebai的专栏 903

2023年下半年网络工程师案例分析真题答案解析

R1] ip route-static 0.0.0.0 0.0.0.0 GigabitEthemet2/0/1 (3) track (4) R1 to R2 //配置R1的缺省路由,联动BFD使得R1到2的流量优先走R1->S1->R2链路,当此链路发生故障时,流量切换到R1->R3->R2链路上。当同一VLAN内也需要网络隔离时,我们可采用交换机的(2)功能,若在配置了二层隔离后,部分主机有互通的需求,则可在需求主机的网关上配置(3)功能。不需要,MAC地址是数据链路层封装以太帧的地址标识。

鹿鸣天涯 748

Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?

Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?   我们来看看Java对内部类的实现。 使用内部类经常是用在Listener这样的。而Listener中的监听函数被调用时,大部分情况,new内部类所在的函数早就执行完了,此时外部类局部变量(保存在栈中)早就因为函数的退出而失效了。   而加上final后,编译器是这样处理内部类的。如果这个外部局部变量是

编程人生 1227

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?...

转载:http://www.haogongju.net/art/461835 java内部类有什么好处?为什么需要内部类? 首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。不过...

WEBCODE 119

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

为什么内部类调用的外部变量必须是final修饰的?

感谢原文:https://blog.youkuaiyun.com/u010393325/article/details/80643636 因为生命周期的原因。方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,如果外部类的方法中的变量不定义final,那么当...

Jason的学习笔记 3569

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

java是内部变量外用_Java 局部 final 变量与内部类引用外部变量

之前一直不明白内部内引用其外部类的变量时此变量必须加 final 修饰只是照着用就是,刚刚就特意百度了下,才明白原来是这么回事!以下内容转自 51CTO本文是Thinking In Java中其中一段的阅读总结。如果定义一个匿名内部类,并且希望它使用一个在其外部定的对象,那么编译器会要求其参数引用是final 的。经研究,Java虚拟机的实现方式是,编译器会探测局部内部类中是否有直接使用外部定义变...

weixin_27282525的博客 201

Java内部类在引用外部类局部变量和成员变量时的区别

1.内部类引用外部类局部变量时,外部类的局部变量一定要用final修饰。 因为内部类和外部类的局部变量生命周期不一样,外部类方法执行完该局部变量可能会被释放掉,但该方法中的内部类可能还在执行(如线程),还要使用该变量,所以外部类变量设置为final的,变成常量,使用的时候内部类可以复制一个副本过去,相当于就不使用该局部变量了。 我们还可以从JVM的角度去解释这个现象,在编译期的时候,所有的类都会被...

weixin_43289620的博客 2888

内部类引用外部类局部变量,外部类局部变量必须是final

Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?

DevXP的专栏 572

内部类访问外部类的局部变量只能是final

public class InnerCalss { private String name = "张三"; @Test public void out(){ String gender = "娜娜"; class Inner{ int in = 1; public void show()...

25k董的博客 694

java为什么匿名内部类的参数引用需要添加final?

参考文章: https://www.zhihu.com/question/21395848 java为什么匿名内部类的参数引用需要添加final? 先看一段代码 这段代码有时可以对外部变量进行赋值,有的又不可以,这是为什么呢? 网上有很多答案,但都没有说明清楚,反而在实验的过程中发现的现象让人越来约迷糊。 public class Index04 { int var1 = 5; A a = new A() { @Override public void met

qq_33106591的博客 1298

为什么内部类访问的外部变量需要使用final修饰

因为生命周期的原因。方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。 首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候,这个局部变量肯定也就被GC了,然而内部类的某个方法还没有执行完,这个时候他所引用的外部变量已

Insist 1万+

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

为什么内部类引用外部类的局部变量时,此变量要用final修饰 代码 public void test() { final int i = 3; runOnUiThread(new Runnable() { @Override public void run() { mTvShow.s

zz276203200的博客 1607

内部类引用局部变量必须为final类型

内部类引用局部变量时必须申明为final,原因有二 一:因为jvm编译后,内部类和外部类是两个独立的calss文件,两者的生命周期不一致,机局部方法所在类运行完后被销毁了,此时内部类还在运行中,会出现内部类访问一个不存在的局部变量,jvm采用在内部类中新增一个成员变量和构造函数(编译时由编译器自动生成),将外部类的局部变量赋值到本类中的成员变量,解决这个问题。 二:若不使用final修饰,会导...

qq_21932931的博客 1625
上一篇: 《心灵捕手》有感
下一篇: android错误:The method makeText(Context, CharSequence, int) in the type
SpeedMe
博客等级 码龄15年 779粉丝 142原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值