前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记录一下编译器怎么老提示我改代码

记录一下编译器怎么老提示我改代码

作者头像
Coder昊白
发布2023-11-22 09:58:40
1090
发布2023-11-22 09:58:40
举报

前言

起因是每次在子线程调用局部变量时编译器爆红,要求参数改为final数组类型,今天心血来潮特地研究一下为什么必须得用final修饰。

一个常见的问题

当我们在子线程调用局部变量时编译器就会提醒我们

image.png
image.png

变量 'test' 在内部类中被访问,需要被声明为 final 或者是事实上的不可变。 当我们添加了final

image.png
image.png

将'test'转换为最终的单元素数组

严谨的编译器

编译器就像一个非常谨慎的管家,总是想要确保你的代码不会闯入奇怪的麻烦。它有点像一个小摄影师,总是让你的代码在镜头前保持最佳状态。当你告诉它要将变量声明为 final 时,它感觉你是在为变量贴上“不可改变”的标签。但是,有时候你可能真的需要在代码中对变量做一些小改动,这时编译器就会变得像一个幽默的小丑,对你说:“哎呀, final 可不是那么容易使用的,得来点儿小花招。” 所以,你加了 final 后,编译器就告诉你,想使用 final 变量,得来点儿“小花招”,比如用数组。这就像你告诉编译器你想做一些小修饰,编译器回应:“哦,你是想要点特色吗?来试试用数组吧,这样我就会觉得你很时尚。”

背后的原因让人暖心

首先我们知道final(保护数据的一致性),这里的一致性指对引用变量的一致性,对基本类型来说就是值的一致性。

为什么需要用final保护数据的一致性呢?

使用 final 修饰变量可以保护数据的一致性,因为它确保在多线程环境中不会出现竞态条件或不一致的状态。在多线程编程中,多个线程同时访问和修改共享变量可能会导致数据不一致的问题,因为线程之间的操作顺序是不确定的。通过使用 final 修饰变量,可以在以下几个方面保护数据的一致性:

  1. 可见性保证: 当一个变量被声明为 final 时,它的值对所有线程都是可见的。这意味着在一个线程中对 final 变量的修改对其他线程立即可见,防止了由于缓存不一致性而引发的问题。
  2. 避免竞态条件: 竞态条件指的是多个线程之间在执行操作的时序上的不确定性,可能导致意外的结果。通过将变量声明为 final,可以避免多个线程同时对变量进行修改,从而消除了竞态条件的风险。
  3. 线程安全性:final 变量是不可修改的,因此在多线程环境下不会发生意外的修改操作。这有助于确保数据的线程安全性,避免了需要使用额外的同步机制来保护变量的情况。

为什么在使用 final 后要使用数组?

当一个变量被声明为 final 后,它的值就不能再被修改。但在一些情况下,我们可能需要在不修改变量本身的前提下,改变其所持有的值。这时,可以使用数组来解决这个问题。 使用数组的主要原因是,数组是引用类型,而 final 关键字只保证引用本身不会被改变,但并不限制引用所指向的对象的内容。因此,我们可以通过将变量声明为指向数组的 final 引用,然后在数组中改变元素的值,达到在 final 变量的限制下修改值的目的。 这种方式相当于“绕过”了 final 关键字的限制,因为数组的引用本身是 final 的,但数组中的元素可以被修改。这在一些需要在不改变变量本身的前提下,改变其持有的值的场景中很有用。 举例来说,如果你需要在一个匿名内部类中修改一个被声明为 final 的变量,可以将该变量包装在一个数组中,并将数组引用声明为 final。然后,在内部类中,你可以修改数组中的元素,从而实现修改值的目的,同时遵循 final 变量的限制。

总结

在之前的Java版本中,当局部变量被匿名内部类引用时,编译器要求该变量为 final 或隐式的 final。这是因为匿名内部类(子线程也算一种匿名内部类)可能会在外部方法执行完毕后继续存在,而局部变量的生命周期通常在方法执行完毕后结束。这可能导致匿名内部类访问无效的变量。 为了解决这个问题,编译器要求变量为 final,这样在匿名内部类中会创建一个拷贝作为成员变量,确保变量的有效性。这样做的好处是,即使局部变量已经消失,匿名内部类仍然可以使用这个不变的成员变量。 然而,在JDK 8之后,编译器对内部类访问外部方法的局部变量进行了改进。不再需要显式声明为 final,因为编译器会自动添加 final 修饰。这使得代码更加简洁,减少了程序员的工作量。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一个常见的问题
  • 严谨的编译器
  • 背后的原因让人暖心
    • 为什么需要用final保护数据的一致性呢?
      • 为什么在使用 final 后要使用数组?
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档