美文网首页程序员
深刻理解从内部类引用的本地变量必须是最终变量或实际上的最终变量这

深刻理解从内部类引用的本地变量必须是最终变量或实际上的最终变量这

作者: 程序圆_ | 来源:发表于2026-01-04 15:07 被阅读0次

1、什么是最终变量,什么是实际变量。

最终变量也就是,有关键字:final修饰的,后面不可改变。

例如:

图1、最终变量

实际变量也就是没有final修饰的变量,但是其在声明时就被赋值后,它的值就没有进行更改。

例如:

图2、实际变量(这里是错误用法)

没有后面的x=20就是effective final。

2、为什么JAVA会出现这个限制。

核心就是其生命周期不一样:局部变量存在方法调用期间,方法结束就被销毁了。而内部类对象可能在方法结束后依然存在,如果内部类直接“引用”局部变量,而该内存已经被释放就会出错。

所以JAVA的解决方案是,Java 在编译时会将局部变量的值拷贝一份给内部类。为了保证语义一致(内部类看到的值不会“意外变化”),这个变量不能被修改。所以会出现问题。

3、修改方案

1、如果是在类中的话可在设计的变量上将局部变量变成实例变量前面加private。

(原因解释:因为外部对象本身必须存在(否则内部类无法存活)那么实例变量也会存在,所以它的成员变量天然就是“可达且一致”的,无需final限制。

例如:

图3、修改方案1

2、可以在局部变量声明前加final(但是如果后面值需要被修改,就会出现错误)

例如:final int  count =0;

3、也可以将局部变量改成数组形式。(不推荐)

(原因解释:后面的内部类引用的是数组的地址,地址并没有进行修改,只是改变了其中的值,所以可以。)

当然聪明的同学想到那不怕出现和局部变量那样的悬挂指针或者已释放内存错误吗?这里解释一下,其数组的引用是放在栈内,而数组本身是放在堆中的,即使方法结束、局部变量销毁,只要内部类还持有对该数组对象的引用,该对象就不会被垃圾回收。

图5、修改方案3

这就是本人对于这个问题的全部理解,希望可以解答大家的疑惑,也望大家在评论中给予补足。

相关文章

  • Cloneable接口

    前置知识 Java在处理对象和变量时是不同的.变量传入函数实际上是引用传入函数内,在函数内的变量和函数外传入的变量...

  • 关于指针

    关于指针 1. 程序对变量的读写操作,实际上是对变量所在的存储空间进行写入或取出数据。 2. 通过变量名引用变量,...

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

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

  • C++要点回顾(谭爷爷的书)

    变量的引用 在C++中,变量的引用就是变量的别名alias 对一个变量的引用的所有操作,实际上都是对其所代表的原来...

  • Linux下的变量

    Linux下的变量 Linux变量 Linux下的变量主要分为三种:本地变量、环境变量和位置变量本地变量本地变量是...

  • 链表(下)写出正确的链表代码的6个技巧

    技巧一:理解指针或引用的含义 指针或引用存储的是对象的内存地址。将某个变量赋值给指针,实际上就是将这个变量的地址赋...

  • 链表(下)—— 6个技巧教你写出正确的链表代码

    技巧一:理解指针或引用的含义 指针或引用存储的是对象的内存地址。将某个变量赋值给指针,实际上就是将这个变量的地址赋...

  • 如何轻松写出正确的链表代码?

    理解指针或引用的含义 含义:将某个变量(对象)赋值给指针(引用),实际上就是就是将这个变量(对象)的地址赋值给指针...

  • Dart(二) 变量与常量

    变量 常量如果定义一个常量,请使用final或const。最终变量只能设置一次;常量变量是编译时常数。(Const...

  • 05 | 链表(下):如何轻松写出正确的链表代码?

    一、理解指针或引用的含义 1.含义:将某个变量(对象)赋值给指针(引用),实际上就是就是将这个变量(对象)的地址赋...

网友评论

    本文标题:深刻理解从内部类引用的本地变量必须是最终变量或实际上的最终变量这

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