当前位置: 首页 > news >正文

java8内部调用无法引用值的问题

问题:Variable used in lambda expression should be final or effectively final

在这里插入图片描述
具体原因:
这段代码试图将 20 赋给一个局部变量,它无法通过编译,但绝非编写错误。
这实际上是语言的设计者有意为之,用以鼓励用户使用 Lambda 表达式获取值而不是变量。
获取值使用户更容易写出没有副作用的代码。
当我们在使用lambda表达式进行函数式编程时候,如何赋值局部变量是不允许的产生这样的原因是因为,lambda表达式是分为及早求值,惰性求值方法俩种方式,因为函数本身就是属于声明式类这样的方式,大大限制了函数内部的拓展使用。
如果一定要使用难免会加大程序的难度和使用,有问题后不易排查,当然这样的问题也不是没有办法,小杨告诉大家方法去处理。

实体类代码:
public static class TestJava8 {

    private int id;private String name;private int age;private int type;public TestJava8(int id, String name, int age, int type) {this.id = id;this.name = name;this.age = age;this.type = type;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getType() {return type;}public void setType(int type) {this.type = type;}
}

使用代码:
//方法2参数
public static List result;

//方法1 参数
public List<TestJava8> result1;@Test
public  void main() {//1 实际业务过滤返回的业务数据TestJava8 testJava81 = new TestJava8(1, "张三", 20, 1);TestJava8 testJava82 = new TestJava8(2, "李四", 30, 2);List<TestJava8> list = new ArrayList<>();list.add(testJava81);list.add(testJava82);AtomicReference<List<TestJava8>> listAtomicReference = new AtomicReference<>();//2 过滤业务数据操作列入对接第三方平台去获取用户类型数据list.stream().forEach(m -> {//3 业务方法使用TestJava8 testJava83 = new TestJava8(4, "王二", 30, 3);TestJava8 testJava84 = new TestJava8(5, "张兰", 50, 4);List<TestJava8> fliterList = new ArrayList<>();fliterList.add(testJava83);fliterList.add(testJava84);//方法1使用getTestJava8List(fliterList);//方法2 使用DataUtils.setResult(fliterList);//方法3 使用listAtomicReference.set(fliterList);//方式4分布式缓存set});System.out.print("方法一获取:" + JSON.toJSONString(result1));System.out.print("方法二获取:" + JSON.toJSONString(DataUtils.getResult()));System.out.print("方法三获取:" + JSON.toJSONString(listAtomicReference.get()));}public static List<TestJava8> getResult() {return result;
}public static void setResult(List<TestJava8> result) {DataUtils.result = result;
}/*** 方法一 使用获取* @param list* @return*/
public List<TestJava8> getTestJava8List(List<TestJava8> list) {result1 = list;return result1;
}

解决方法一:

编写方法去接收,通过对象属性赋值的特性。
//定一一个集合
public List result;
/**
* 定义本地方法返回
* @param list
* @return
*/
public List getTestJava8List(List list) {
this.result =list;
return result;
}

解决方法二:定静态属性值

静态可以缓存到常量池里面,所以有一定缓存时间,其实这种就是jvm的本地缓存
public static List result;

public static List<TestJava8> getResult() {return result;
}public static void setResult(List<TestJava8> result) {DataUtils.result = result;
}获取://2 过滤业务数据操作列入对接第三方平台去获取用户类型数据list.stream().forEach(m -> {//3 业务方法使用TestJava8 testJava83 = new TestJava8(4, "王二", 30, 3);TestJava8 testJava84 = new TestJava8(5, "张兰", 50, 4);List<TestJava8> fliterList = new ArrayList<>();fliterList.add(testJava83);fliterList.add(testJava84);DataUtils.setResult(fliterList);});

使用:
DataUtils.getResult();

解决方法三:通过cas无锁的机制,内存交换原子操作AtomicReference 通过这个存入数据,既能解决当前的问题,还能保证线程的数据安全问题,通常是用这个。

使用方式:
AtomicReference<List> listAtomicReference = new AtomicReference<>();
//2 过滤业务数据操作列入对接第三方平台去获取用户类型数据
list.stream().forEach(m -> {
//3 业务方法使用
TestJava8 testJava83 = new TestJava8(4, “王二”, 30, 3);
TestJava8 testJava84 = new TestJava8(5, “张兰”, 50, 4);
List fliterList = new ArrayList<>();
fliterList.add(testJava83);
fliterList.add(testJava84);

            listAtomicReference.set(fliterList);});

获取: listAtomicReference.get();使用即可

解决方法四:分布式缓存

使用分布式缓存,或者第三方缓存都是能够获取到参数值的,但是对数据的一致性要求不是那么高的时候我推荐使用第三种方式,如果对数据一致性要求比较高的话就使用分布式缓存,多个服务之间共享处理,如果是比较简单单体我推荐使用第一种方式,没有很多并发和请求。

————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)

http://www.lryc.cn/news/91333.html

相关文章:

  • 《嵌入式系统》知识总结10:使用位带操作操纵GPIO
  • leetcode 2.两数相加(链表操作)
  • Jenkins是什么?以及Jenkins有哪些具体的应用呢?
  • 2023年数学建模:参数估计与假设检验:自助法(Bootstrap)详解
  • 华为OD机试真题 Java 实现【字符串通配符】【2022Q4 200分】
  • Android 11.0 user模式下解除系统进入recovery功能的限制
  • TDEngine3.0 环境安装、配置及使用经验总结
  • Redis7实战加面试题-高阶篇(Redlock算法和底层源码分析)
  • 保持Git历史提交整洁,解决冲突
  • CompletableFuture使用详解,多线程相关
  • (3)NUC980 kenerl编译
  • 华为OD机试真题 Java 实现【分奖金】【2022Q4 100分】
  • 迅为国产化RK3588开发板在安防前后端应用解决方案
  • Windows 安装 GCC
  • 下载安装LabVIEW
  • 从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
  • Java NIO-非阻塞I/O(二)
  • PaaS平台iuap——数智底座支撑企业的全球化业务拓展
  • RK3318 android12 HEVC-1080P 4K VP9等格式视频播放不了
  • gpt技术简介以及具体应用领域
  • 【java】leetcode 二叉树展开为链表
  • windows环境, nginx https配置
  • git 命令
  • 【高分论文密码】大尺度空间模拟预测与数字制图
  • Word控件Aspose.Words教程:使用 C# 读取 SXC 和 FODS 文件
  • 代码示范【FabEdge v0.8.0】配置 connector 公开端口
  • 通过Python的PyPDF2库合并多个pdf文件
  • python基础 - python命名空间与作用域
  • MapReduce实战案例(3)
  • Socket(三)